diff --git a/.cypress/plugins/index.js b/.cypress/plugins/index.js
deleted file mode 100644
index b7a464331..000000000
--- a/.cypress/plugins/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-///
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-
-/**
- * @type {Cypress.PluginConfig}
- */
-module.exports = (on, config) => {
- // `on` is used to hook into various events Cypress emits
- // `config` is the resolved Cypress config
-}
diff --git a/.cypress/support/commands.js b/.cypress/support/commands.js
deleted file mode 100644
index e4d90a391..000000000
--- a/.cypress/support/commands.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-// ***********************************************
-// This example commands.js shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add("login", (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
diff --git a/.cypress/support/index.js b/.cypress/support/index.js
deleted file mode 100644
index 17c275f42..000000000
--- a/.cypress/support/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-// ***********************************************************
-// This example support/index.js is processed and
-// loaded automatically before your test files.
-//
-// This is a great place to put global configuration and
-// behavior that modifies Cypress.
-//
-// You can change the location of this file or turn off
-// automatically serving support files with the
-// 'supportFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/configuration
-// ***********************************************************
-
-// Import commands.js using ES2015 syntax:
-import './commands'
-
-// Alternatively you can use CommonJS syntax:
-// require('./commands')
diff --git a/.cypress/utils/constants.js b/.cypress/utils/constants.js
deleted file mode 100644
index aae37564d..000000000
--- a/.cypress/utils/constants.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-export const delay = 1500;
-export const TRACE_ID = '8832ed6abbb2a83516461960c89af49d';
-export const SPAN_ID = 'a673bc074b438374';
-export const SERVICE_NAME = 'frontend-client';
-
-export const setTimeFilter = (setEndTime = false, refresh = true) => {
- const startTime = 'Mar 25, 2021 @ 10:00:00.000';
- const endTime = 'Mar 25, 2021 @ 11:00:00.000';
- cy.get('button.euiButtonEmpty[aria-label="Date quick select"]').click();
- cy.get('.euiQuickSelect__applyButton').click();
- cy.get('.euiSuperDatePicker__prettyFormatLink').click();
- cy.get(
- 'button.euiDatePopoverButton--start[data-test-subj="superDatePickerstartDatePopoverButton"]'
- ).click();
- cy.get('.euiTab__content').contains('Absolute').click();
- cy.get('input[data-test-subj="superDatePickerAbsoluteDateInput"]')
- .focus()
- .type('{selectall}' + startTime);
- if (setEndTime) {
- cy.wait(delay);
- cy.get(
- 'button.euiDatePopoverButton--end[data-test-subj="superDatePickerendDatePopoverButton"]'
- ).click();
- cy.wait(delay);
- cy.get('.euiTab__content').contains('Absolute').click();
- cy.get('input[data-test-subj="superDatePickerAbsoluteDateInput"]')
- .focus()
- .type('{selectall}' + endTime);
- }
- if (refresh) cy.get('.euiButton__text').contains('Refresh').click();
- cy.wait(delay);
-};
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index e80769cbf..000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-module.exports = {
- root: true,
- extends: [
- '@elastic/eslint-config-kibana',
- 'plugin:@elastic/eui/recommended',
- 'plugin:react-hooks/recommended',
- ],
-};
-
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 000000000..a2f03f8c3
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+# This should match the owning team set up in https://github.com/orgs/opensearch-project/teams
+* @opensearch-project/trace-analytics
\ No newline at end of file
diff --git a/.github/draft-release-notes-config.yml b/.github/draft-release-notes-config.yml
new file mode 100644
index 000000000..371f1b065
--- /dev/null
+++ b/.github/draft-release-notes-config.yml
@@ -0,0 +1,45 @@
+# The overall template of the release notes
+template: |
+ Compatible with OpenSearch and OpenSearch Dashboards Version $RESOLVED_VERSION
+ $CHANGES
+
+# Setting the formatting and sorting for the release notes body
+name-template: Version $RESOLVED_VERSION
+change-template: "* $TITLE ([#$NUMBER](https://github.com/opensearch-project/observability/pull/$NUMBER))"
+sort-by: merged_at
+sort-direction: ascending
+replacers:
+ - search: '##'
+ replace: '###'
+
+# Organizing the tagged PRs into unified categories
+categories:
+ - title: 'Breaking Changes'
+ labels:
+ - 'Breaking Changes'
+ - title: 'Features'
+ labels:
+ - 'feature'
+ - title: 'Enhancements'
+ labels:
+ - 'enhancement'
+ - title: 'Bug Fixes'
+ labels:
+ - 'bug'
+ - title: 'Infrastructure'
+ labels:
+ - 'infra'
+ - 'test'
+ - 'dependencies'
+ - 'github actions'
+ - title: 'Documentation'
+ labels:
+ - 'documentation'
+ - title: 'Maintenance'
+ labels:
+ - "version compatibility"
+ - "maintenance"
+ - title: 'Refactoring'
+ labels:
+ - 'refactor'
+ - 'code quality'
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
new file mode 100644
index 000000000..e47d8d88c
--- /dev/null
+++ b/.github/workflows/backport.yml
@@ -0,0 +1,28 @@
+name: Backport
+on:
+ pull_request_target:
+ types:
+ - closed
+ - labeled
+
+jobs:
+ backport:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ name: Backport
+ steps:
+ - name: GitHub App token
+ id: github_app_token
+ uses: tibdex/github-app-token@v1.5.0
+ with:
+ app_id: ${{ secrets.APP_ID }}
+ private_key: ${{ secrets.APP_PRIVATE_KEY }}
+ installation_id: 22958780
+
+ - name: Backport
+ uses: VachaShah/backport@v1.1.4
+ with:
+ github_token: ${{ steps.github_app_token.outputs.token }}
+ branch_name: backport/backport-${{ github.event.number }}
diff --git a/.github/workflows/test-and-build-workflow.yml b/.github/workflows/dashboards-observability-test-and-build-workflow.yml
similarity index 65%
rename from .github/workflows/test-and-build-workflow.yml
rename to .github/workflows/dashboards-observability-test-and-build-workflow.yml
index d37b5145f..7de3170c0 100644
--- a/.github/workflows/test-and-build-workflow.yml
+++ b/.github/workflows/dashboards-observability-test-and-build-workflow.yml
@@ -1,12 +1,12 @@
-name: Test and Build Trace Analytics
+name: Test and Build Observability Dashboards Plugin
on: [pull_request, push]
env:
- PLUGIN_NAME: trace-analytics-dashboards
- OPENSEARCH_VERSION: '1.0'
- OPENSEARCH_PLUGIN_VERSION: 1.0.0.0
+ PLUGIN_NAME: dashboards-observability
+ OPENSEARCH_VERSION: '1.3'
+ OPENSEARCH_PLUGIN_VERSION: 1.3.4.0
jobs:
@@ -15,6 +15,9 @@ jobs:
runs-on: ubuntu-latest
steps:
+ - name: Checkout Plugin
+ uses: actions/checkout@v1
+
- name: Checkout OpenSearch Dashboards
uses: actions/checkout@v2
with:
@@ -40,36 +43,36 @@ jobs:
echo "Installing yarn ${{ steps.versions_step.outputs.yarn_version }}"
npm i -g yarn@${{ steps.versions_step.outputs.yarn_version }}
- - name: Checkout Plugin
- uses: actions/checkout@v2
- with:
- path: OpenSearch-Dashboards/plugins/trace-analytics
+ - name: Move Observability to Plugins Dir
+ run: mv dashboards-observability OpenSearch-Dashboards/plugins/dashboards-observability
- name: Plugin Bootstrap
run: |
- cd OpenSearch-Dashboards/plugins/trace-analytics
+ cd OpenSearch-Dashboards/plugins/dashboards-observability
yarn osd bootstrap
- - name: Test
+ - name: Test all dashboards-observability modules
run: |
- cd OpenSearch-Dashboards/plugins/trace-analytics
+ cd OpenSearch-Dashboards/plugins/dashboards-observability
yarn test --coverage
- name: Upload coverage
uses: codecov/codecov-action@v1
with:
+ flags: dashboards-observability
+ directory: ./OpenSearch-Dashboards/plugins/dashboards-observability
token: ${{ secrets.CODECOV_TOKEN }}
- direcotry: ./OpenSearch-Dashboards/plugins/trace-analytics
+ # TODO remove hard coded version when observability is ready
- name: Build Artifact
run: |
- cd OpenSearch-Dashboards/plugins/trace-analytics
+ cd OpenSearch-Dashboards/plugins/dashboards-observability
yarn build
mv ./build/*.zip ./build/${{ env.PLUGIN_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip
- name: Upload Artifact
uses: actions/upload-artifact@v1
with:
- name: trace-analytics
- path: ./OpenSearch-Dashboards/plugins/trace-analytics/build
+ name: dashboards-observability
+ path: ./OpenSearch-Dashboards/plugins/dashboards-observability/build
diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml
new file mode 100644
index 000000000..cf30ea89d
--- /dev/null
+++ b/.github/workflows/dco.yml
@@ -0,0 +1,18 @@
+name: Developer Certificate of Origin Check
+
+on: [pull_request]
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Get PR Commits
+ id: 'get-pr-commits'
+ uses: tim-actions/get-pr-commits@v1.1.0
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ - name: DCO Check
+ uses: tim-actions/dco@v1.1.0
+ with:
+ commits: ${{ steps.get-pr-commits.outputs.commits }}
diff --git a/.github/workflows/delete_backport_branch.yml b/.github/workflows/delete_backport_branch.yml
new file mode 100644
index 000000000..387a124b8
--- /dev/null
+++ b/.github/workflows/delete_backport_branch.yml
@@ -0,0 +1,15 @@
+name: Delete merged branch of the backport PRs
+on:
+ pull_request:
+ types:
+ - closed
+
+jobs:
+ delete-branch:
+ runs-on: ubuntu-latest
+ if: startsWith(github.event.pull_request.head.ref,'backport/')
+ steps:
+ - name: Delete merged branch
+ uses: SvanBoxel/delete-merged-branch@main
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/draft-release-notes-workflow.yml b/.github/workflows/draft-release-notes-workflow.yml
new file mode 100644
index 000000000..2c4567d39
--- /dev/null
+++ b/.github/workflows/draft-release-notes-workflow.yml
@@ -0,0 +1,21 @@
+name: Release Drafter
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ update_release_draft:
+ name: Update draft release notes
+ runs-on: ubuntu-latest
+ steps:
+ # Drafts your next Release notes as Pull Requests are merged into "main"
+ - name: Update draft release notes
+ uses: release-drafter/release-drafter@v5
+ with:
+ config-name: draft-release-notes-config.yml
+ tag: (None)
+ version: x.x.0.0
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml
index 5e6fd3942..ed4ce699e 100644
--- a/.github/workflows/link-checker.yml
+++ b/.github/workflows/link-checker.yml
@@ -16,7 +16,7 @@ jobs:
id: lychee
uses: lycheeverse/lychee-action@master
with:
- args: --accept=200,403,429 "**/*.html" "**/*.md" "**/*.txt"
+ args: --accept=200,403,429 "./**/*.html" "./**/*.md" "./**/*.txt"
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Fail if there were link errors
diff --git a/.github/workflows/opensearch-observability-test-and-build-workflow.yml b/.github/workflows/opensearch-observability-test-and-build-workflow.yml
new file mode 100644
index 000000000..3b3c62f67
--- /dev/null
+++ b/.github/workflows/opensearch-observability-test-and-build-workflow.yml
@@ -0,0 +1,56 @@
+name: Test and Build OpenSearch Observability Backend Plugin
+
+on: [pull_request, push]
+
+env:
+ OPENSEARCH_VERSION: '1.3.2-SNAPSHOT'
+ OPENSEARCH_BRANCH: '1.3'
+ COMMON_UTILS_BRANCH: 'main'
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ java:
+ - 8
+ - 11
+ - 14
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v1
+ with:
+ java-version: ${{ matrix.java }}
+
+ - name: Run Backwards Compatibility Tests
+ run: |
+ cd opensearch-observability
+ echo "Running backwards compatibility tests ..."
+ ./gradlew bwcTestSuite -Dtests.security.manager=false
+
+ - name: Build with Gradle
+ run: |
+ cd opensearch-observability
+ ./gradlew build -Dopensearch.version=${{ env.OPENSEARCH_VERSION }}
+
+ - name: Upload coverage
+ uses: codecov/codecov-action@v1
+ with:
+ flags: opensearch-observability
+ directory: opensearch-observability/
+ token: ${{ secrets.CODECOV_TOKEN }}
+
+ - name: Create Artifact Path
+ run: |
+ mkdir -p opensearch-observability-builds
+ cp -r ./opensearch-observability/build/distributions/*.zip opensearch-observability-builds/
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v1
+ with:
+ name: opensearch-observability
+ path: opensearch-observability-builds
diff --git a/.github/workflows/release-workflow.yml b/.github/workflows/release-workflow.yml
deleted file mode 100644
index 622384075..000000000
--- a/.github/workflows/release-workflow.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-name: Release Trace Analytics Artifacts
-
-on:
- push:
- tags:
- - 'v*'
-
-env:
- PLUGIN_NAME: trace-analytics-dashboards
- OPENSEARCH_VERSION: '1.0'
- OPENSEARCH_PLUGIN_VERSION: 1.0.0.0
-
-jobs:
-
- build:
-
- runs-on: ubuntu-latest
-
- steps:
-
- - name: Configure AWS Credentials
- uses: aws-actions/configure-aws-credentials@v1
- with:
- aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
- aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- aws-region: us-east-1
-
- - name: Checkout OpenSearch Dashboards
- uses: actions/checkout@v1
- with:
- repository: opensearch-project/Opensearch-Dashboards
- ref: ${{ env.OPENSEARCH_VERSION }}
- path: OpenSearch-Dashboards
-
- - name: Checkout Plugin
- uses: actions/checkout@v1
- with:
- path: OpenSearch-Dashboards/plugins/trace-analytics
-
- - name: Setup Node
- uses: actions/setup-node@v1
- with:
- node-version: '10.23.1'
-
- - name: Plugin Bootstrap
- run: |
- yarn osd bootstrap
-
- - name: Build Artifact
- run: |
- yarn build
- mv ./build/*.zip ./build/${{ env.PLUGIN_NAME }}-${{ env.OPENSEARCH_PLUGIN_VERSION }}.zip
- artifact=`ls ./build/*.zip`
-
- # TODO change to new bucket
- aws s3 cp $artifact s3://artifacts.opendistroforelasticsearch.amazon.com/downloads/kibana-plugins/opendistro-trace-analytics/
- aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/downloads/*"
diff --git a/.whitesource b/.whitesource
new file mode 100644
index 000000000..db4b0fec8
--- /dev/null
+++ b/.whitesource
@@ -0,0 +1,15 @@
+{
+ "scanSettings": {
+ "configMode": "AUTO",
+ "configExternalURL": "",
+ "projectToken": "",
+ "baseBranches": []
+ },
+ "checkRunSettings": {
+ "vulnerableCheckRunConclusionLevel": "failure",
+ "displayMode": "diff"
+ },
+ "issueSettings": {
+ "minSeverityLevel": "LOW"
+ }
+}
\ No newline at end of file
diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md
index 1ef0de10e..0d38ef640 100644
--- a/DEVELOPER_GUIDE.md
+++ b/DEVELOPER_GUIDE.md
@@ -2,15 +2,35 @@
So you want to contribute code to this project? Excellent! We're glad you're here. Here's what you need to do.
+### Install Prerequisites
+
+#### JDK 11
+
+OpenSearch builds using Java 11 at a minimum. This means you must have a JDK 11
+installed with the environment variable `JAVA_HOME` referencing the path to Java home
+for your JDK 11 installation, e.g. `JAVA_HOME=/usr/lib/jvm/jdk-11`.
+
+By default, tests use the same runtime as `JAVA_HOME`. However, since OpenSearch
+supports JDK 8, the build supports compiling with JDK 11 and testing on a different
+version of JDK runtime. To do this, set `RUNTIME_JAVA_HOME` pointing to the Java home of
+another JDK installation, e.g. `RUNTIME_JAVA_HOME=/usr/lib/jvm/jdk-8`.
+
### Setup
-1. Download OpenSearch for the version that matches the [OpenSearch Dashboards version specified in package.json](./package.json#L5).
-1. Download the OpenSearch Dashboards source code for the [version specified in package.json](./package.json#L5) you want to set up.
+1. Download OpenSearch for the version that matches the [OpenSearch Dashboards version specified in package.json](./dashboards-observability/package.json#L5).
+1. Download the OpenSearch Dashboards source code for the [version specified in package.json](./dashboards-observability/package.json#L5) you want to set up.
1. Change your node version to the version specified in `.node-version` inside the OpenSearch Dashboards root directory.
1. cd into `plugins` directory in the OpenSearch Dashboards source code directory.
1. Check out this package from version control into the `plugins` directory.
-1. Run `yarn osd bootstrap` inside `OpenSearch-Dashboards/plugins/trace-analytics`.
+```bash
+git clone git@github.com:opensearch-project/observability.git plugins --no-checkout
+cd plugins
+echo 'dashboards-observability/*' >> .git/info/sparse-checkout
+git config core.sparseCheckout true
+git checkout main
+```
+6. Run `yarn osd bootstrap` inside `OpenSearch-Dashboards/plugins/dashboards-observability`.
Ultimately, your directory structure should look like this:
@@ -18,14 +38,14 @@ Ultimately, your directory structure should look like this:
.
├── OpenSearch-Dashboards
│ └── plugins
-│ └── trace-analytics
+│ └── dashboards-observability
```
### Build
To build the plugin's distributable zip simply run `yarn build`.
-Example output: `./build/trace-analytics-dashboards*.zip`
+Example output: `./build/observability*.zip`
### Run
@@ -36,3 +56,11 @@ Example output: `./build/trace-analytics-dashboards*.zip`
### Submitting Changes
See [CONTRIBUTING](CONTRIBUTING.md).
+
+### Backports
+
+The Github workflow in [`backport.yml`](.github/workflows/backport.yml) creates backport PRs automatically when the original PR
+with an appropriate label `backport ` is merged to main with the backport workflow run successfully on the
+PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label `backport 1.x` to the PR and make sure the
+backport workflow runs on the PR along with other checks. Once this PR is merged to main, the workflow will create a backport PR
+to the `1.x` branch.
\ No newline at end of file
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index a925ab2d9..683c66959 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -1,7 +1,11 @@
-# Trace Analytics Maintainers
+# Observability Maintainers
## Maintainers
-| Maintainer | GitHub ID | Affiliation |
-|------------------------|---------------------------------------------------|-------------|
-| David Cui | [davidcui-amzn](https://github.com/davidcui-amzn) | Amazon |
-| Joshua Li | [joshuali925](https://github.com/joshuali925) | Amazon |
+| Maintainer | GitHub ID | Affiliation |
+|---------------|-------------------------------------------------|-------------|
+| David Cui | [davidcui1225](https://github.com/davidcui1225) | Amazon |
+| Eric Wei | [mengweieric](https://github.com/mengweieric) | Amazon |
+| Joshua Li | [joshuali925](https://github.com/joshuali925) | Amazon |
+| Shenoy Pratik | [ps48](https://github.com/ps48) | Amazon |
+| Kavitha Mohan | [kavithacm] (https://github.com/kavithacm) | Amazon |
+| Eugene Lee | [eugenesk24] (https://github.com/eugenesk24) | Amazon |
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
index be83767d4..731cb6006 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,12 +1,2 @@
-OpenSearch
-Copyright 2021 OpenSearch Contributors
-
-This product includes software developed by
-Elasticsearch (http://www.elastic.co).
-Copyright 2009-2018 Elasticsearch
-
-This product includes software developed by The Apache Software
-Foundation (http://www.apache.org/).
-
-This product includes software developed by
-Joda.org (http://www.joda.org/).
+OpenSearch (https://opensearch.org/)
+Copyright OpenSearch Contributors
diff --git a/README.md b/README.md
index 6ca939537..87feb1c1e 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,98 @@
-[![Trace Analytics CI](https://github.com/opensearch-project/trace-analytics/actions/workflows/test-and-build-workflow.yml/badge.svg)](https://github.com/opensearch-project/trace-analytics/actions/workflows/test-and-build-workflow.yml)
-[![codecov](https://codecov.io/gh/opensearch-project/trace-analytics/branch/main/graphs/badge.svg)](https://codecov.io/gh/opensearch-project/trace-analytics)
-
-# OpenSearch Dashboards Trace Analytics
-
-The OpenSearch Dashboards Trace Analytics plugin provides instant on dashboards in OpenSearch Dashboards for users to quickly analyze their logs. The plugin uses aggregated results from two indices, `otel-v1-apm-span-*` and `otel-v1-apm-service-map*` created by the otel-trace-raw-processor and service-map-processor, and renders three main views:
+
+
+- [Observability](#observability)
+- [Code Summary](#code-summary)
+- [Plugin Components](#plugin-components)
+- [Documentation](#documentation)
+- [Contributing](#contributing)
+- [Getting Help](#getting-help)
+- [Code of Conduct](#code-of-conduct)
+- [Security](#security)
+- [License](#license)
+- [Copyright](#copyright)
+
+# Observability
+
+Observability is collection of plugins and applications that let you visualize data-driven events by using Piped Processing Language to explore, discover, and query data stored in OpenSearch.
+
+## Code Summary
+
+### OpenSearch-Observability
+
+| | |
+| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| Test and build | [![Observability OpenSearch Build CI][opensearch-build-badge]][opensearch-build-link] |
+| Code coverage | [![codecov][opensearch-codecov-badge]][codecov-link] |
+| Distribution build tests | [![OpenSearch IT tests][opensearch-it-badge]][opensearch-it-link] [![OpenSearch IT code][opensearch-it-code-badge]][opensearch-it-code-link] |
+| Backward compatibility tests | [![BWC tests][bwc-tests-badge]][bwc-tests-link] |
+
+### Dashboards-Observability
+
+| | |
+| ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
+| Test and build | [![Observability Dashboards CI][dashboard-build-badge]][dashboard-build-link] |
+| Code coverage | [![codecov][dashboard-codecov-badge]][codecov-link] |
+| Distribution build tests | [![cypress tests][cypress-test-badge]][cypress-test-link] [![cypress code][cypress-code-badge]][cypress-code-link] |
+
+### Repository Checks
+
+| | |
+| ------------ | --------------------------------------------------------------- |
+| DCO Checker | [![Developer certificate of origin][dco-badge]][dco-badge-link] |
+| Link Checker | [![Link Checker][link-check-badge]][link-check-link] |
+
+### Issues
+
+| |
+| -------------------------------------------------------------- |
+| [![good first issues open][good-first-badge]][good-first-link] |
+| [![features open][feature-badge]][feature-link] |
+| [![enhancements open][enhancement-badge]][enhancement-link] |
+| [![bugs open][bug-badge]][bug-link] |
+| [![untriaged open][untriaged-badge]][untriaged-link] |
+| [![nolabel open][nolabel-badge]][nolabel-link] |
+
+[dco-badge]: https://github.com/opensearch-project/observability/actions/workflows/dco.yml/badge.svg
+[dco-badge-link]: https://github.com/opensearch-project/observability/actions/workflows/dco.yml
+[link-check-badge]: https://github.com/opensearch-project/observability/actions/workflows/link-checker.yml/badge.svg
+[link-check-link]: https://github.com/opensearch-project/observability/actions/workflows/link-checker.yml
+[dashboard-build-badge]: https://github.com/opensearch-project/observability/actions/workflows/dashboards-observability-test-and-build-workflow.yml/badge.svg
+[dashboard-build-link]: https://github.com/opensearch-project/observability/actions/workflows/dashboards-observability-test-and-build-workflow.yml
+[opensearch-build-badge]: https://github.com/opensearch-project/observability/actions/workflows/opensearch-observability-test-and-build-workflow.yml/badge.svg
+[opensearch-build-link]: https://github.com/opensearch-project/observability/actions/workflows/opensearch-observability-test-and-build-workflow.yml
+[dashboard-codecov-badge]: https://codecov.io/gh/opensearch-project/observability/branch/main/graphs/badge.svg?flag=dashboards-observability
+[opensearch-codecov-badge]: https://codecov.io/gh/opensearch-project/observability/branch/main/graphs/badge.svg?flag=opensearch-observability
+[codecov-link]: https://codecov.io/gh/opensearch-project/observability
+[cypress-test-badge]: https://img.shields.io/badge/Cypress%20tests-in%20progress-yellow
+[cypress-test-link]: https://github.com/opensearch-project/opensearch-build/issues/1124
+[cypress-code-badge]: https://img.shields.io/badge/Cypress%20code-blue
+[cypress-code-link]: https://github.com/opensearch-project/observability/blob/main/dashboards-observability/.cypress/CYPRESS_TESTS.md
+[opensearch-it-badge]: https://img.shields.io/badge/OpenSearch%20Plugin%20IT%20tests-in%20progress-yellow
+[opensearch-it-link]: https://github.com/opensearch-project/opensearch-build/issues/1124
+[opensearch-it-code-badge]: https://img.shields.io/badge/OpenSearch%20IT%20code-blue
+[opensearch-it-code-link]: https://github.com/opensearch-project/observability/blob/main/opensearch-observability/src/test/kotlin/org/opensearch/observability/ObservabilityPluginIT.kt
+[bwc-tests-badge]: https://img.shields.io/badge/BWC%20tests-in%20progress-yellow
+[bwc-tests-link]: https://github.com/opensearch-project/observability/issues/276
+[good-first-badge]: https://img.shields.io/github/issues/opensearch-project/observability/good%20first%20issue.svg
+[good-first-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+
+[feature-badge]: https://img.shields.io/github/issues/opensearch-project/observability/feature.svg
+[feature-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+label%3Afeature
+[bug-badge]: https://img.shields.io/github/issues/opensearch-project/observability/bug.svg
+[bug-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+label%3Abug+
+[enhancement-badge]: https://img.shields.io/github/issues/opensearch-project/observability/enhancement.svg
+[enhancement-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement+
+[untriaged-badge]: https://img.shields.io/github/issues/opensearch-project/observability/untriaged.svg
+[untriaged-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+label%3Auntriaged+
+[nolabel-badge]: https://img.shields.io/github/issues-search/opensearch-project/observability?color=yellow&label=no%20label%20issues&query=is%3Aopen%20is%3Aissue%20no%3Alabel
+[nolabel-link]: https://github.com/opensearch-project/observability/issues?q=is%3Aopen+is%3Aissue+no%3Alabel+
+
+## Plugin Components
+
+The Observability plugin has four components: Trace Analytics, Event Analytics, Operational Panels, and Notebooks.
+
+### Trace Analytics
+
+Trace Analytics page provides instant on dashboards in OpenSearch Dashboards for users to quickly analyze their logs. The plugin uses aggregated results from two indices, `otel-v1-apm-span-*` and `otel-v1-apm-service-map*` created by the otel-trace-raw-processor and service-map-processor, and renders three main views:
1. Dashboard: an overview of the trace groups and three charts: error rate, throughput, service map.
@@ -13,19 +102,31 @@ The OpenSearch Dashboards Trace Analytics plugin provides instant on dashboards
Additionally the fields can be sorted and filtered.
+### Event Analytics
+
+Event Analytics allows user to monitor, correlate, analyze and visualize machine generated data through [Piped Processing Language](https://opensearch.org/docs/latest/observability-plugins/ppl/index/). It also enables the user to turn data-driven events into visualizations and save frequently used ones for quick access.
+
+### Operational Panels
+
+Operational panels provides the users to create and view different visualizations on ingested observability data, using Piped Processing Language queries. Use PPL 'where clauses' and datetime timespans to filter all visualizations in the panel.
+
+### Notebooks
+
+Dashboards offer a solution for a few selected use cases, and are great tools if you’re focused on monitoring a known set of metrics over time. Notebooks enables contextual use of data with detailed explanations by allowing a user to combine saved visualizations, text, graphs and decorate data with other reference data sources.
+
## Documentation
-Please see our technical [documentation](https://docs-beta.opensearch.org/monitoring-plugins/trace/index/) to learn more about its features.
+Please see our technical [documentation](https://opensearch.org/docs/latest/observability/index/) to learn more about its features.
## Contributing
-See [developer guide](DEVELOPER_GUIDE.md) and [how to contribute to this project](CONTRIBUTING.md).
+See [developer guide](DEVELOPER_GUIDE.md) and [how to contribute to this project](CONTRIBUTING.md).
## Getting Help
If you find a bug, or have a feature request, please don't hesitate to open an issue in this repository.
-For more information, see [project website](https://opensearch.org/) and [documentation](https://docs-beta.opensearch.org/). If you need help and are unsure where to open an issue, try [forums](https://discuss.opendistrocommunity.dev/).
+For more information, see [project website](https://opensearch.org/) and [documentation](https://opensearch.org/docs). If you need help and are unsure where to open an issue, try [forums](https://discuss.opendistrocommunity.dev/).
## Code of Conduct
@@ -37,8 +138,8 @@ If you discover a potential security issue in this project we ask that you notif
## License
-This project is licensed under the [Apache v2.0 License](LICENSE.txt).
+This project is licensed under the [Apache v2.0 License](LICENSE).
## Copyright
-Copyright 2020-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+Copyright OpenSearch Contributors. See [NOTICE](NOTICE) for details.
diff --git a/common/index.ts b/common/index.ts
deleted file mode 100644
index d273efa16..000000000
--- a/common/index.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-export const PLUGIN_ID = 'trace-analytics-dashboards';
-export const PLUGIN_NAME = 'Trace Analytics';
-
-export const RAW_INDEX_NAME = 'otel-v1-apm-span-*';
-export const SERVICE_MAP_INDEX_NAME = 'otel-v1-apm-service-map*';
-export const DATE_FORMAT = 'MM/DD/YYYY HH:mm:ss';
-export const DATE_PICKER_FORMAT = 'MMM D, YYYY HH:mm:ss';
-export const SERVICE_MAP_MAX_NODES = 500;
-// size limit when requesting edge related queries, not necessarily the number of edges
-export const SERVICE_MAP_MAX_EDGES = 1000;
-export const TRACES_MAX_NUM = 3000;
-export const DOCUMENTATION_LINK = 'https://docs-beta.opensearch.org/monitoring-plugins/trace/';
-
diff --git a/.babelrc b/dashboards-observability/.babelrc
similarity index 100%
rename from .babelrc
rename to dashboards-observability/.babelrc
diff --git a/dashboards-observability/.cypress/CYPRESS_TESTS.md b/dashboards-observability/.cypress/CYPRESS_TESTS.md
new file mode 100644
index 000000000..bba2db259
--- /dev/null
+++ b/dashboards-observability/.cypress/CYPRESS_TESTS.md
@@ -0,0 +1,146 @@
+# Observability Cypress Test Cases
+The observability plugin currently has 4 modules in it. Each of the modules have their own cypress tests [here](./integration).
+
+## 1. Event Analytics
+
+### Home
+
+* Query Search
+ * Type query in search bar then click ‘refresh’ button on date range picker to search would redirect user to explorer page, and display searching results in that page
+ * Click ‘refresh’ button directly without having a query in search bar would redirect user to explorer page with a new empty tab
+* Actions - Event Explorer
+ * Click ‘Event explorer’ in the dropdown list of actions would redirect user to explorer page
+* Actions - Delete
+ * Check saved queries and(or) saved visualizations then click delete in dropdown list of actions is expected to delete selected saved objects’
+* Actions - Add Samples
+ * Click ‘add samples’ in the dropdown list of actions is expected to add 9 sample saved queries and visualizations, the newly added samples is expected to shop up in Queries and Visualizations table
+
+### Explorer
+
+* Add new tabs
+
+ * Click ’add new‘ button is expected to add top level tabs
+ * Redirections from clicking history links is expected to
+ * create new tab if there’s already tab with searched data
+ * populate the the first empty tab
+ * Redirections from clicking ‘new query’ in home page would always create new tab
+
+* Close tabs
+
+ * Close unselected tab should close that tab only, and not change the current selected tab
+ * Click ‘add new’ to add new tabs and click on any tab before the last created tab, then close that tab. It is expected to close the current tab properly, and newly selected tab is expected to be one tab before it if there’s any existing tabs or the immediate tab comes after the deleted one
+ * It is expected to be not able to close a tab when there’s only one tab left, and user will be prompt with a toast message
+
+* Query Saving
+
+ * Saves a query on event tab of explorer page is expected to create a new saved query. The user should see this new saved query in Queries and Visualizations table.
+ * Saves a visualization on visualization tab of explorer page is expected to create a new saved visualization. The user should see this new saved Visualization Queries and Visualizations table on event home should display this new saved visualization
+ * Saves a visualization to existing panels
+* Sidebar
+ * Search fields
+ * Toggle fields between selected and available fields categories
+ * Override timestamp
+ * Click on a timestamp field to override timestamp is expected to create a new saved, default timestamp for this index
+* Count distribution
+ * Change time interval
+ * Display event counts
+* Visualization tab
+ * Switch visualizations from dropdown list
+* Data Grid
+ * Expand/collapse a data entry
+
+## 2. Custom panels
+
+### Home Table
+
+* Check panel name validity
+* Create and open a new panel
+* Duplicate and rename a panel
+* Search an existing panel
+* Delete panels
+
+### Create Visualization
+
+* Create two visualizations in events explorer
+
+### Panel View
+
+* Move to test panel
+* Duplicate using panel action
+* Rename using panel action
+* Change date filter
+* Add existing visualizations
+* Add ppl filter to the panel
+* Drag and Drop Visualization in edit mode
+* Resize a Visualization in edit mode
+* Delete a Visualization in edit mode
+* Duplicate a Visualization
+* Replace a Visualization
+* Create a new Visualization and directly add to an existing panel
+* Edit a Visualization and check the change in panels
+
+### Clean Up
+
+* Add Samples
+* Verify sample visualization names in sample panel
+* Delete All Visualization from event analytics
+* Delete all Panels
+
+## 3. Notebooks
+
+* Displays error toast for invalid notebook name
+* Creates a notebook and redirects to the notebook
+* Duplicates and renames a notebook
+* Searches existing notebooks
+* Deletes notebooks
+* Create in-context PDF report from notebook
+* Create in-context PNG report from notebook
+* Create on-demand report definition from context menu
+* Goes into a notebook and creates paragraphs
+* Renders markdown
+* Shows output message
+* Renders input only mode
+* Renders output only mode
+* Duplicates paragraphs
+* Adds a dashboards visualization paragraph
+* Adds an observability visualization paragraph
+* Adds a SQL query paragraph
+* Adds a PPL query paragraph
+* Clears outputs
+* Runs all paragraphs
+* Adds paragraph to top and bottom
+* Moves paragraphs
+* Duplicates and renames the notebook
+* Deletes paragraphs
+* Deletes notebook
+
+## 4. Trace analytics
+
+### Dashboard
+
+* Indexes test data
+* Renders empty state
+* Renders the dashboard table
+* Adds the percentile filters
+* Opens latency trend popover
+* Redirects to traces table with filter
+* Renders service map
+* Renders plots
+
+### Service
+
+* Renders empty state
+* Renders the services table
+* Searches correctly
+* Renders service view empty state
+* Renders service view
+* Renders spans data grid, flyout, filters
+
+### Trace
+
+* Renders empty state
+* Renders the traces table
+* Searches correctly
+* Renders the trace view
+* Renders data grid, flyout and filters
+
diff --git a/dashboards-observability/.cypress/integration/1_event_analytics.spec.js b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js
new file mode 100644
index 000000000..02e79b33f
--- /dev/null
+++ b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js
@@ -0,0 +1,460 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+///
+import {
+ delay,
+ TEST_QUERIES,
+ TESTING_PANEL,
+ SAVE_QUERY1,
+ SAVE_QUERY2,
+ SAVE_QUERY3,
+ SAVE_QUERY4,
+} from '../utils/constants';
+import { supressResizeObserverIssue } from '../utils/constants';
+
+const landOnEventHome = () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics`);
+ cy.wait(delay);
+};
+
+const landOnEventExplorer = () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics/explorer`
+ );
+ cy.wait(delay * 2);
+};
+
+const landOnPanels = () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels`
+ );
+ cy.wait(delay);
+};
+
+const querySearch = (query) => {
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(query);
+ cy.get('[data-test-subj="superDatePickerToggleQuickMenuButton"]').click();
+ cy.get('[data-test-subj="superDatePickerCommonlyUsed_This_year"]').click();
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+};
+
+describe('Adding sample data and visualization', () => {
+ it('Adds sample flights data for event analytics', () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/home#/tutorial_directory/sampleData`);
+ cy.get('div[data-test-subj="sampleDataSetCardflights"]')
+ .contains(/(Add|View) data/)
+ .click();
+ cy.wait(delay);
+ });
+});
+
+describe('Has working breadcrumbs', () => {
+ it('Redirect to correct page on breadcrumb click', () => {
+ landOnEventExplorer();
+ cy.wait(delay * 3);
+ cy.get('.euiBreadcrumb[href="#/event_analytics/explorer"]').contains('Explorer').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('exist');
+ cy.get('.euiBreadcrumb[href="#/event_analytics"]').contains('Event analytics').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ cy.get('.euiBreadcrumb[href="observability-dashboards#/"]').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+});
+
+describe('Open flyout for a data row to see details', () => {
+ beforeEach(() => {
+ landOnEventExplorer();
+ });
+
+ it('Should be able to open flyout and see data, json and traces', () => {
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="docTable"] tbody tr button.euiButtonIcon').first().click();
+ cy.get('.observability-flyout').should('exist');
+ cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('JSON').click();
+ cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('Traces').click();
+ cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('Table').click();
+ });
+
+ it('Should be able to see srrounding docs', () => {
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="docTable"] tbody tr button.euiButtonIcon').first().click();
+ cy.get('.observability-flyout').should('exist');
+ cy.get('.observability-flyout span.euiButton__text').contains('View surrounding events').click();
+ cy.get('.observability-flyout #surroundingFyout').contains('View surrounding events').should('exist');
+ });
+});
+
+describe('Search a query on event home', () => {
+ it('Search a query and redirect to explorer to display result data', () => {
+ landOnEventHome();
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+
+ cy.url().should('contain', '#/event_analytics/explorer');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').contains(TEST_QUERIES[0].query);
+ });
+});
+
+describe('Add/delete/switch explorer top level tabs', () => {
+ beforeEach(() => {
+ landOnEventExplorer();
+ });
+
+ it('Add a new tab', () => {
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength + 1);
+ });
+ });
+
+ it('Click to switch to anther tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .first()
+ .click();
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .first()
+ .should('have.class', 'euiTab-isSelected');
+ });
+
+ it('Close a tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"] button.euiTab')
+ .first()
+ .find('[data-test-subj="eventExplorer__tabClose"]')
+ .click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength - 1);
+ });
+ });
+
+ it('Close current selected tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"] button.euiTab').eq(1).click();
+ cy.get('button.euiTab-isSelected [data-test-subj="eventExplorer__tabClose"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength - 1);
+ });
+ });
+
+ it('Close another unselected tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('button.euiTab').first().find('[data-test-subj="eventExplorer__tabClose"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength - 1);
+ });
+ });
+});
+
+describe('Load a saved query from event home', () => {
+ it('Click on a saved query and redirect to explorer', () => {
+ landOnEventExplorer();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+
+ cy.get('.tab-title').contains('Events').click();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY4);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+
+ landOnEventHome();
+
+ cy.get('[data-test-subj="eventHome__savedQueryTableName"]')
+ .first()
+ .contains(SAVE_QUERY4)
+ .click();
+ cy.wait(delay);
+
+ cy.url().should('contain', '#/event_analytics/explorer');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').contains(TEST_QUERIES[0].query);
+ });
+});
+
+describe('Click actions', () => {
+ beforeEach(() => {
+ landOnEventHome();
+ });
+
+ it('Actions - click event explorer', () => {
+ cy.get('[data-test-subj="eventHomeAction"]').click();
+ cy.get('[data-test-subj="eventHomeAction__explorer"]').click();
+ cy.wait(delay);
+ cy.url().should('contain', '#/event_analytics/explorer');
+ });
+
+ it('Actions - add sample data', () => {
+ cy.get('[data-test-subj="eventHomeAction"]').click();
+ cy.get('[data-test-subj="eventHomeAction__addSamples"]').click();
+ cy.get('[data-test-subj="confirmModalConfirmButton"]').click();
+ cy.wait(delay * 2);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+
+ it('Actions - delete saved queries', () => {
+ cy.get('[data-test-subj^="checkboxSelectRow"]').first().check();
+ cy.get('[data-test-subj="eventHomeAction"]').click();
+ cy.get('[data-test-subj="eventHomeAction__delete"]').click();
+ cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
+ cy.get('[data-test-subj="popoverModal__deleteButton"').click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+});
+
+describe('Saves a query on explorer page', () => {
+ it('Saves a query on event tab of explorer page', () => {
+ landOnEventExplorer();
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[0].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+
+ cy.get('.tab-title').contains('Events').click();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY1);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+
+ landOnEventHome();
+
+ cy.get('[data-test-subj="eventHome__savedQueryTableName"]').first().contains(SAVE_QUERY1);
+ });
+
+ it('Saves a visualization on visualization tab of explorer page', () => {
+ landOnEventExplorer();
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+ supressResizeObserverIssue();
+ cy.get('button[id="main-content-vis"]').contains('Visualizations').click();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY2);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+
+ landOnEventHome();
+
+ cy.get('[data-test-subj="eventHome__savedQueryTableName"]').first().contains(SAVE_QUERY2);
+ });
+
+ it('Saves a visualization to an existing panel', () => {
+ landOnPanels();
+
+ cy.get('[data-test-subj="customPanels__createNewPanels"]').click();
+ cy.get('input.euiFieldText').type(TESTING_PANEL);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay);
+
+ landOnEventExplorer();
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.wait(delay);
+
+ supressResizeObserverIssue();
+ cy.get('button[id="main-content-vis"]').contains('Visualizations').click();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY3);
+ cy.get('[data-test-subj="eventExplorer__querySaveComboBox"]').type(TESTING_PANEL);
+ cy.get(`input[value="${TESTING_PANEL}"]`).click();
+ cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+});
+
+describe('Override default timestamp for an index', () => {
+ it('Click override button to override default timestamp', () => {
+ landOnEventExplorer();
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[2].query);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click();
+ cy.get('.tab-title').contains('Events').click();
+ cy.get('[data-test-subj="eventExplorer__overrideDefaultTimestamp"]').click();
+ cy.wait(delay);
+
+ cy.get('[data-attr-field="utc_time"] [data-test-subj="eventFields__default-timestamp-mark"')
+ .contains('Default Timestamp').should('exist');
+ cy.get('[data-attr-field="timestamp"] [data-test-subj="eventFields__default-timestamp-mark"').should('not.exist');
+ });
+});
+
+describe('Toggle sidebar fields', () => {
+ it('Toggle fields between available and selected section', () => {
+ landOnEventExplorer();
+ querySearch(TEST_QUERIES[0].query);
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="fieldToggle-AvgTicketPrice"]').click();
+ cy.get('[data-test-subj="field-AvgTicketPrice"]').should('exist');
+ cy.get('[data-test-subj="docTable"]').find('th').contains('_source').should('not.exist');
+ cy.get('[data-test-subj="fieldToggle-AvgTicketPrice"]').click();
+ cy.get('[data-test-subj="field-AvgTicketPrice"]').should('exist');
+ cy.get('[data-test-subj="docTable"]').find('th').contains('_source').should('exist');
+ });
+});
+
+describe('Search fields in sidebar', () => {
+ it('Search a field', () => {
+ landOnEventExplorer();
+ querySearch(TEST_QUERIES[0].query);
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="eventExplorer__sidebarSearch"]').type('A');
+ cy.get('[data-test-subj="field-Cancelled"]').should('not.exist');
+ cy.get('[data-test-subj="field-AvgTicketPrice"]').should('exist');
+ cy.get('[data-test-subj="field-DestAirportID"]').should('exist');
+ cy.get('[data-test-subj="field-OriginAirportID"]').should('exist');
+ });
+});
+
+describe('Delete saved objects', () => {
+ it('Delete visualizations/querys from event analytics', () => {
+ landOnEventHome();
+ cy.get('[data-test-subj="tablePaginationPopoverButton"]').click();
+ cy.get('.euiContextMenuItem__text').contains('50 rows').click();
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+ cy.wait(delay);
+ cy.get('.euiTextAlign').contains('No Queries or Visualizations').should('exist');
+ });
+});
+
+describe('Switch on and off livetail', () => {
+ it('Switch on and off in live tail', () => {
+ landOnEventExplorer();
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query);
+
+ cy.get('[data-test-subj=eventLiveTail]').click();
+ cy.get('[data-test-subj=eventLiveTail__delay10s]').click();
+ cy.wait(delay * 2);
+ cy.get('.euiToastHeader__title').contains('On').should('exist');
+
+ cy.get('[data-test-subj=eventLiveTail__off').click();
+ cy.wait(delay * 2);
+ cy.get('.euiToastHeader__title').contains('Off').should('exist');
+ });
+});
+
+describe('Live tail stop automatically', () => {
+ it('Moving to other tab should stop live tail automatically', () => {
+ landOnEventExplorer();
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(TEST_QUERIES[1].query);
+
+ cy.get('[data-test-subj=eventLiveTail]').click();
+ cy.get('[data-test-subj=eventLiveTail__delay10s]').click();
+ cy.wait(delay * 2);
+ cy.get('.euiToastHeader__title').contains('On').should('exist');
+ });
+
+ it('Add a new tab', () => {
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength + 1);
+ });
+});
+
+ it('Click to switch to another tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .first()
+ .click();
+ cy.wait(delay);
+
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .first()
+ .should('have.class', 'euiTab-isSelected');
+});
+
+ it('Close current selected tab', () => {
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__addNewTab"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .then((lists) => {
+ const initialLength = Cypress.$(lists).length;
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"] button.euiTab').eq(1).click();
+ cy.get('button.euiTab-isSelected [data-test-subj="eventExplorer__tabClose"]').click();
+ cy.get('[data-test-subj="eventExplorer__topLevelTabbing"]')
+ .find('button.euiTab')
+ .should('have.length', initialLength - 1);
+ });
+ });
+
+ it('Live tail should be stopped', () => {
+ cy.get('.euiButton__text').contains('Live');
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/.cypress/integration/2_notebooks.spec.js b/dashboards-observability/.cypress/integration/2_notebooks.spec.js
new file mode 100644
index 000000000..d15b922a7
--- /dev/null
+++ b/dashboards-observability/.cypress/integration/2_notebooks.spec.js
@@ -0,0 +1,463 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+///
+
+import {
+ delay,
+ TEST_NOTEBOOK,
+ MARKDOWN_TEXT,
+ SAMPLE_URL,
+ SQL_QUERY_TEXT,
+ PPL_QUERY_TEXT,
+} from '../utils/constants';
+
+import { SAMPLE_PANEL } from '../utils/panel_constants';
+
+import { skipOn } from '@cypress/skip-test';
+
+describe('Adding sample data and visualization', () => {
+ it('Adds sample flights data for visualization paragraph', () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/home#/tutorial_directory/sampleData`);
+ cy.get('div[data-test-subj="sampleDataSetCardflights"]')
+ .contains(/(Add|View) data/)
+ .click();
+ });
+
+ it('Add sample observability data', () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
+ );
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.get('.euiContextMenuItem__text').contains('Add samples').click();
+ cy.get('.euiModalHeader__title[data-test-subj="confirmModalTitleText"]')
+ .contains('Add samples')
+ .should('exist');
+ cy.get('.euiButton__text').contains('Yes').click();
+ cy.wait(delay * 5);
+ cy.get('.euiTableCellContent').contains(SAMPLE_PANEL).should('exist');
+ });
+});
+
+describe('Testing notebooks table', () => {
+ beforeEach(() => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/notebooks`);
+ });
+
+ it('Displays error toast for invalid notebook name', () => {
+ cy.get('.euiButton__text').contains('Create notebook').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('Invalid notebook name').should('exist');
+ });
+
+ it('Creates a notebook and redirects to the notebook', () => {
+ cy.get('.euiButton__text').contains('Create notebook').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(TEST_NOTEBOOK);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay);
+
+ cy.contains(TEST_NOTEBOOK).should('exist');
+ });
+
+ it('Duplicates and renames a notebook', () => {
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Duplicate').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Duplicate').click();
+ cy.wait(delay);
+
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(1).click();
+ cy.wait(delay);
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Rename').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(' (rename)');
+ cy.get('.euiButton__text').contains('Rename').click();
+ cy.wait(delay);
+ });
+
+ it('Searches existing notebooks', () => {
+ cy.get('input.euiFieldSearch').type('this notebook should not exist');
+ cy.wait(delay);
+
+ cy.get('.euiTableCellContent__text').contains('No items found').should('exist');
+
+ cy.get('.euiFormControlLayoutClearButton').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldSearch').type(TEST_NOTEBOOK + ' (copy) (rename)');
+ cy.wait(delay);
+
+ cy.get('a.euiLink')
+ .contains(TEST_NOTEBOOK + ' (copy) (rename)')
+ .should('exist');
+ });
+
+ it('Deletes notebooks', () => {
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+
+ cy.get('.euiTextAlign').contains('No notebooks').should('exist');
+
+ // keep a notebook for testing
+ cy.get('.euiButton__text').contains('Create notebook').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(TEST_NOTEBOOK);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay * 2);
+ });
+});
+
+describe('Test reporting integration if plugin installed', () => {
+ beforeEach(() => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/notebooks`);
+ cy.get('.euiTableCellContent').contains(TEST_NOTEBOOK).click();
+ cy.wait(delay * 3);
+ cy.get('body').then(($body) => {
+ skipOn($body.find('#reportingActionsButton').length <= 0);
+ });
+ });
+
+ it('Create in-context PDF report from notebook', () => {
+ cy.get('#reportingActionsButton').click();
+ cy.wait(delay);
+ cy.get('button.euiContextMenuItem:nth-child(1)').contains('Download PDF').click();
+ cy.get('#downloadInProgressLoadingModal').should('exist');
+ });
+
+ it('Create in-context PNG report from notebook', () => {
+ cy.get('#reportingActionsButton').click();
+ cy.wait(delay);
+ cy.get('button.euiContextMenuItem:nth-child(2)').contains('Download PNG').click();
+ cy.get('#downloadInProgressLoadingModal').should('exist');
+ });
+
+ it('Create on-demand report definition from context menu', () => {
+ cy.get('#reportingActionsButton').click();
+ cy.wait(delay);
+ cy.get('button.euiContextMenuItem:nth-child(3)').contains('Create report definition').click();
+ cy.wait(delay);
+ cy.location('pathname', { timeout: 60000 }).should('include', '/reports-dashboards');
+ cy.wait(delay);
+ cy.get('#reportSettingsName').type('Create notebook on-demand report');
+ cy.get('#createNewReportDefinition').click({ force: true });
+ });
+
+ it('View reports homepage from context menu', () => {
+ cy.get('#reportingActionsButton').click();
+ cy.wait(delay);
+ cy.get('button.euiContextMenuItem:nth-child(4)').contains('View reports').click();
+ cy.wait(delay);
+ cy.location('pathname', { timeout: 60000 }).should('include', '/reports-dashboards');
+ });
+});
+
+describe('Testing paragraphs', () => {
+ beforeEach(() => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/notebooks`);
+ cy.get('.euiTableCellContent').contains(TEST_NOTEBOOK).click();
+ });
+
+ it('Goes into a notebook and creates paragraphs', () => {
+ cy.get('.euiButton__text').contains('Add').click();
+ cy.wait(delay);
+
+ cy.get('.euiTextArea').should('exist');
+
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ cy.get('.euiTextColor').contains('Input is required.').should('exist');
+ cy.get('.euiTextArea').clear();
+ cy.get('.euiTextArea').type(MARKDOWN_TEXT);
+ cy.wait(delay);
+
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ });
+
+ it('Has working breadcrumbs', () => {
+ cy.get('.euiBreadcrumb').contains(TEST_NOTEBOOK).click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains(TEST_NOTEBOOK).should('exist');
+ cy.get('.euiBreadcrumb').contains('Notebooks').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Notebooks').should('exist');
+ cy.get('.euiBreadcrumb').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+
+ it('Renders markdown', () => {
+ cy.get('.euiTextArea').should('not.exist');
+ cy.get(`a[href="${SAMPLE_URL}"]`).should('exist');
+ cy.get('code').contains('POST').should('exist');
+ cy.get('td').contains('b2').should('exist');
+ });
+
+ it('Shows output message', () => {
+ cy.get('button[aria-label="Toggle show input"]').click();
+ cy.wait(delay);
+ cy.get('.euiTextColor').contains('Last successful run').should('exist');
+
+ cy.get('pre.input').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiTextArea').type('Another text');
+ cy.wait(delay);
+
+ cy.get('.euiTextColor').contains('Last successful run').should('exist');
+ });
+
+ it('Renders input only mode', () => {
+ cy.get('.euiToggle__input[title="Input only"]').click();
+ cy.wait(delay);
+
+ cy.get('div.markdown-body').should('not.exist');
+ cy.get('.euiLink').contains('View both').should('exist');
+ cy.get('.euiLink').contains('View both').click();
+ cy.wait(delay);
+
+ cy.get('code').contains('POST').should('exist');
+ cy.get('.euiLink').contains('View both').should('not.exist');
+ });
+
+ it('Renders output only mode', () => {
+ cy.get('.euiToggle__input[title="Output only"]').click();
+ cy.wait(delay);
+
+ cy.get('button[aria-label="Open paragraph menu"]').should('not.exist');
+ cy.get('button[aria-label="Toggle show input"]').should('not.exist');
+ cy.get('code').contains('POST').should('exist');
+ });
+
+ it('Duplicates paragraphs', () => {
+ cy.get('.euiButtonIcon[aria-label="Open paragraph menu"]').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Duplicate').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+
+ cy.get(`a[href="${SAMPLE_URL}"]`).should('have.length.gte', 2);
+ });
+
+ it('Adds a dashboards visualization paragraph', () => {
+ cy.contains('Add paragraph').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Visualization').click();
+ cy.wait(delay);
+
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ cy.get('.euiTextColor').contains('Visualization is required.').should('exist');
+
+ cy.get('.euiButton__text').contains('Browse').click();
+ cy.wait(delay);
+ cy.get('.euiFieldSearch').focus().type('[Flights] Flight Count and Average Ticket Price{enter}');
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Select').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ cy.get('div.visualization').should('exist');
+ });
+
+ it('Adds a SQL query paragraph', () => {
+ cy.contains('Add paragraph').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Code block').click();
+ cy.wait(delay);
+
+ cy.get('.euiTextArea').type(SQL_QUERY_TEXT);
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay * 5);
+
+ cy.get('b').contains('select * from opensearch_dashboards_sample_data_flights limit 20');
+
+ cy.get('.euiDataGrid__overflow').should('exist');
+ });
+
+ it('Adds an observability visualization paragraph', () => {
+ cy.contains('Add paragraph').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Visualization').click();
+ cy.wait(delay);
+
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ cy.get('.euiTextColor').contains('Visualization is required.').should('exist');
+
+ cy.get('.euiButton__text').contains('Browse').click();
+ cy.wait(delay);
+ cy.get('.euiFieldSearch').focus().type('[Logs] Count total requests by tags{enter}');
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Select').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay);
+ cy.get('h5').contains('[Logs] Count total requests by tags').should('exist');
+ });
+
+ it('Adds a PPL query paragraph', () => {
+ cy.contains('Add paragraph').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Code block').click();
+ cy.wait(delay);
+
+ cy.get('.euiTextArea').type(PPL_QUERY_TEXT);
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Run').click();
+ cy.wait(delay * 5);
+
+ cy.get('b').contains('source=opensearch_dashboards_sample_data_flights');
+
+ cy.get('.euiDataGrid__overflow').should('exist');
+ });
+
+ it('Clears outputs', () => {
+ cy.wait(delay * 3); // need to wait for paragraphs to load first
+ cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Clear all outputs').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Clear').click();
+ cy.wait(delay);
+
+ cy.get(`a[href="${SAMPLE_URL}"]`).should('not.exist');
+ });
+
+ it('Runs all paragraphs', () => {
+ cy.wait(delay * 3); // need to wait for paragraphs to load first
+ cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Run all paragraphs').click();
+ cy.wait(delay);
+
+ cy.get(`a[href="${SAMPLE_URL}"]`).should('exist');
+ });
+
+ it('Adds paragraph to top and bottom', () => {
+ cy.wait(delay * 3); // need to wait for paragraphs to load first
+ cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Add paragraph to top').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Code block').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Add paragraph to bottom').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Code block').click();
+ cy.wait(delay);
+
+ cy.get('.euiText').contains('[4] Visualization').should('exist');
+ cy.get('.euiText').contains('[5] Code block').should('exist');
+ });
+
+ it('Moves paragraphs', () => {
+ cy.get('.euiButtonIcon[aria-label="Open paragraph menu"').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem-isDisabled').should('have.length.gte', 2);
+ cy.get('.euiContextMenuItem__text').contains('Move to bottom').click();
+ cy.wait(delay);
+
+ cy.get('.euiText').contains('[3] Visualization').should('exist');
+ });
+
+ it('Duplicates and renames the notebook', () => {
+ cy.get('[data-test-subj="notebook-notebook-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Duplicate notebook').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Duplicate').click();
+ cy.wait(delay * 3);
+
+ cy.get('[data-test-subj="notebook-notebook-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Rename notebook').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText[data-autofocus="true"]').type(' (rename)');
+ cy.wait(delay);
+ cy.get('.euiButton__text').last().contains('Rename').click();
+ cy.wait(delay);
+ cy.reload();
+ cy.wait(delay * 3);
+
+ cy.get('.euiTitle')
+ .contains(TEST_NOTEBOOK + ' (copy) (rename)')
+ .should('exist');
+ cy.get(`a[href="${SAMPLE_URL}"]`).should('have.length.gte', 2);
+ });
+
+ it('Deletes paragraphs', () => {
+ cy.wait(delay * 3);
+ cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete all paragraphs').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('.euiTextAlign').contains('No paragraphs').should('exist');
+ });
+
+ it('Deletes notebook', () => {
+ cy.get('[data-test-subj="notebook-notebook-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete notebook').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+ cy.wait(delay * 3);
+
+ cy.get('.euiButton__text').contains('Create notebook').should('exist');
+ });
+
+ it('Cleans up test notebooks', () => {
+ cy.get('[data-test-subj="notebook-notebook-actions-button"]').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete notebook').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+ cy.wait(delay * 3);
+
+ cy.get('.euiText').contains('No notebooks').should('exist');
+ });
+});
diff --git a/dashboards-observability/.cypress/integration/3_panels.spec.js b/dashboards-observability/.cypress/integration/3_panels.spec.js
new file mode 100644
index 000000000..1c3ed1cb6
--- /dev/null
+++ b/dashboards-observability/.cypress/integration/3_panels.spec.js
@@ -0,0 +1,493 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+///
+
+import {
+ delay,
+ TEST_PANEL,
+ PPL_VISUALIZATIONS,
+ PPL_VISUALIZATIONS_NAMES,
+ NEW_VISUALIZATION_NAME,
+ PPL_FILTER,
+ SAMPLE_PANEL,
+ SAMPLE_VISUALIZATIONS_NAMES,
+} from '../utils/panel_constants';
+
+import { supressResizeObserverIssue } from '../utils/constants';
+
+const moveToEventsHome = () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics/`);
+ cy.wait(delay * 3);
+};
+
+const moveToPanelHome = () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
+ );
+ cy.wait(delay * 3);
+};
+
+const moveToTestPanel = () => {
+ moveToPanelHome();
+ cy.get('.euiTableCellContent').contains(TEST_PANEL).click();
+ cy.wait(delay * 3);
+ cy.get('h1').contains(TEST_PANEL).should('exist');
+ cy.wait(delay);
+};
+
+describe('Adding sample data and visualization', () => {
+ it('Adds sample flights data for visualization paragraph', () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/home#/tutorial_directory/sampleData`);
+ cy.get('div[data-test-subj="sampleDataSetCardflights"]')
+ .contains(/(Add|View) data/)
+ .click();
+ cy.wait(delay * 3);
+ });
+});
+
+describe('Creating visualizations', () => {
+ beforeEach(() => {
+ moveToEventsHome();
+ });
+
+ it('Create first visualization in event analytics', () => {
+ cy.get('[id^=autocomplete-textarea]').type(PPL_VISUALIZATIONS[0]);
+ cy.get('.euiButton__text').contains('Refresh').click();
+ cy.wait(delay);
+ supressResizeObserverIssue();
+ cy.get('button[id="main-content-vis"]').contains('Visualizations').click();
+ cy.wait(delay * 2);
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.wait(delay * 2);
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(PPL_VISUALIZATIONS_NAMES[0]);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+
+ it('Create second visualization in event analytics', () => {
+ cy.get('[id^=autocomplete-textarea]').type(PPL_VISUALIZATIONS[1]);
+ cy.get('.euiButton__text').contains('Refresh').click();
+ cy.wait(delay);
+ supressResizeObserverIssue();
+ cy.get('button[id="main-content-vis"]').contains('Visualizations').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(PPL_VISUALIZATIONS_NAMES[1]);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+});
+
+describe('Testing panels table', () => {
+ beforeEach(() => {
+ moveToPanelHome();
+ });
+
+ it('Displays error toast for invalid panel name', () => {
+ cy.get('.euiButton__text').contains('Create panel').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay);
+
+ cy.get('.euiToastHeader__title').contains('Invalid Operational Panel name').should('exist');
+ });
+
+ it('Creates a panel and redirects to the panel', () => {
+ cy.get('.euiButton__text').contains('Create panel').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(TEST_PANEL);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay);
+
+ cy.contains(TEST_PANEL).should('exist');
+ });
+
+ it('Duplicates and renames a panel', () => {
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Duplicate').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Duplicate').click();
+ cy.wait(delay);
+
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(1).click();
+ cy.wait(delay);
+ cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Rename').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(' (rename)');
+ cy.get('.euiButton__text').contains('Rename').click();
+ cy.wait(delay);
+ });
+
+ it('Searches existing panel', () => {
+ cy.get('input.euiFieldSearch').type('this panel should not exist');
+ cy.wait(delay);
+
+ cy.get('.euiTableCellContent__text').contains('No items found').should('exist');
+
+ cy.get('.euiFormControlLayoutClearButton').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldSearch').type(TEST_PANEL + ' (copy) (rename)');
+ cy.wait(delay);
+
+ cy.get('a.euiLink')
+ .contains(TEST_PANEL + ' (copy) (rename)')
+ .should('exist');
+ });
+
+ it('Deletes panels', () => {
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+
+ cy.get('.euiTextAlign').contains('No Operational Panels').should('exist');
+
+ // keep a panel for testing
+ cy.get('.euiButton__text').contains('Create panel').click();
+ cy.wait(delay);
+ cy.get('input.euiFieldText').type(TEST_PANEL);
+ cy.get('.euiButton__text')
+ .contains(/^Create$/)
+ .click();
+ cy.wait(delay * 2);
+ });
+});
+
+describe('Testing a panel', () => {
+ it('Move to test panel', () => {
+ moveToTestPanel();
+ });
+
+ it('Opens visualization flyout from empty panel', () => {
+ cy.get('.euiButton').eq(4).contains('Add visualization').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Select existing visualization').click();
+ cy.wait(delay);
+ cy.get('.euiButton').contains('Cancel').click();
+ cy.get('.euiButton').eq(2).contains('Add visualization').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Select existing visualization').click();
+ cy.wait(delay);
+ cy.get('.euiButton').contains('Cancel').click();
+ cy.get('.euiButton').contains('Add visualization').first().click();
+ cy.get('.euiContextMenuItem__text').contains('Create new visualization').click();
+ cy.wait(delay);
+ cy.get('.euiBreadcrumb').contains('Explorer').should('exist');
+ cy.get('.euiCallOut').contains('No results match your search criteria').should('exist');
+ });
+
+ it('Redirects to correct page on breadcrumb click', () => {
+ moveToTestPanel();
+ cy.get('.euiBreadcrumb').contains(TEST_PANEL).click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains(TEST_PANEL).should('exist');
+ cy.get('.euiBreadcrumb').contains('Operational panels').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Operational panels').should('exist');
+ cy.get('.euiBreadcrumb').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+
+ it('Duplicate the open panel', () => {
+ moveToTestPanel();
+ cy.get('.euiButton__text').contains('Panel actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Duplicate panel').click();
+ cy.wait(delay);
+ cy.get(`input.euiFieldText[value="${TEST_PANEL} (copy)"]`).should('exist');
+ cy.get('.euiButton__text').contains('Duplicate').click();
+ cy.wait(delay * 3);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ cy.get('h1')
+ .contains(TEST_PANEL + ' (copy)')
+ .should('exist');
+ cy.wait(delay);
+ });
+
+ it('Rename the open panel', () => {
+ cy.get('.euiButton__text').contains('Panel actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Rename panel').click();
+ cy.wait(delay);
+ cy.get(`input.euiFieldText[value="${TEST_PANEL} (copy)"]`)
+ .focus()
+ .clear()
+ .type('Renamed Panel');
+ cy.get('.euiButton__text').contains('Rename').click();
+ cy.wait(delay * 3);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ cy.get('h1').contains('Renamed Panel').should('exist');
+ cy.wait(delay);
+ });
+
+ it('Change date filter of the panel', () => {
+ moveToTestPanel();
+ cy.get('.euiButtonEmpty[data-test-subj="superDatePickerToggleQuickMenuButton"]').click();
+ cy.get('.euiLink').contains('This year').click();
+ cy.wait(delay * 2);
+ cy.get('.euiSuperDatePicker__prettyFormat[data-test-subj="superDatePickerShowDatesButton"]')
+ .contains('This year')
+ .should('exist');
+ cy.wait(delay);
+ });
+
+ it('Add existing visualization #1', () => {
+ cy.get('.euiButton__text').contains('Add visualization').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Select existing visualization').click();
+ cy.wait(delay);
+ cy.get('select').select(PPL_VISUALIZATIONS_NAMES[0]);
+ cy.get('button[aria-label="refreshPreview"]').click();
+ cy.wait(delay * 2);
+ cy.get('.plot-container').should('exist');
+ cy.get('.euiButton__text').contains(new RegExp('^Add$', 'g')).click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+
+ it('Add existing visualization #2', () => {
+ cy.get('.euiButton__text').contains('Add visualization').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Select existing visualization').click();
+ cy.wait(delay);
+ cy.get('select').select(PPL_VISUALIZATIONS_NAMES[1]);
+ cy.get('button[aria-label="refreshPreview"]').click();
+ cy.wait(delay * 2);
+ cy.get('.plot-container').should('exist');
+ cy.get('.euiButton__text').contains(new RegExp('^Add$', 'g')).click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ });
+
+ it('Add ppl filter to panel', () => {
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]')
+ .click()
+ .wait(1500)
+ .type("where Carrier = 'OpenSearch-Air'| where Dest = 'Munich Airport'", {delay: 500});
+ cy.get('.euiButton__text').contains('Refresh').click();
+ cy.wait(delay * 3);
+ cy.get('.xtick').should('contain', 'OpenSearch-Air');
+ cy.get('.xtick').should('contain', 'Munich Airport');
+ cy.get('.xtick').contains('Zurich Airport').should('not.exist');
+ cy.get('.xtick').contains('BeatsWest').should('not.exist');
+ cy.get('.xtick').contains('Logstash Airways').should('not.exist');
+ cy.get('.xtick').contains('OpenSearch Dashboards Airlines').should('not.exist');
+ cy.wait(delay);
+ });
+
+ it('Drag and drop a visualization', () => {
+ cy.get('.euiButton__text').contains('Edit').click();
+ cy.wait(delay);
+ cy.get('h5')
+ .contains(PPL_VISUALIZATIONS_NAMES[1])
+ .trigger('mousedown', { which: 1 })
+ .trigger('mousemove', { clientX: 1100, clientY: 0 })
+ .trigger('mouseup', { force: true });
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Save').click();
+ cy.wait(delay * 3);
+ cy.get('div.react-grid-layout>div')
+ .eq(1)
+ .invoke('attr', 'style')
+ .should('match', new RegExp('(.*)transform: translate((.*)10px)(.*)'));
+ cy.wait(delay);
+ });
+
+ it('Resize a visualization', () => {
+ cy.get('.euiButton__text').contains('Edit').click();
+ cy.wait(delay);
+ cy.get('.react-resizable-handle')
+ .eq(1)
+ .trigger('mousedown', { which: 1 })
+ .trigger('mousemove', { clientX: 2000, clientY: 800 })
+ .trigger('mouseup', { force: true });
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Save').click();
+ cy.wait(delay * 3);
+ cy.get('div.react-grid-layout>div').eq(1).invoke('height').should('match', new RegExp('470'));
+ cy.wait(delay);
+ });
+
+ it('Delete a visualization', () => {
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[1]).should('exist');
+ cy.get('.euiButton__text').contains('Edit').click();
+ cy.wait(delay);
+ cy.get('.visualization-action-button').eq(1).click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Save').click();
+ cy.wait(delay * 3);
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[1]).should('not.exist');
+ cy.wait(delay);
+ });
+
+ it('Duplicate a visualization', () => {
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.get('button[aria-label="actionMenuButton"]').click();
+ cy.get('.euiContextMenu__itemLayout > .euiContextMenuItem__text').contains('Duplicate').click();
+ cy.wait(delay * 2);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ cy.wait(delay);
+ cy.get('h5').eq(0).contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.get('h5').eq(1).contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.wait(delay);
+ });
+
+ it('Replace a visualization', () => {
+ cy.get('.visualization-action-button').eq(1).click();
+ cy.get('.euiContextMenu__itemLayout > .euiContextMenuItem__text').contains('Replace').click();
+ cy.get('select').select(PPL_VISUALIZATIONS_NAMES[1]);
+ cy.get('button[aria-label="refreshPreview"]').click();
+ cy.wait(delay * 3);
+ cy.get('.plot-container').should('exist');
+ cy.get('.euiButton__text').contains(new RegExp('^Add$', 'g')).click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ cy.wait(delay);
+ cy.get('h5').eq(0).contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.get('h5').eq(1).contains(PPL_VISUALIZATIONS_NAMES[1]).should('exist');
+ cy.wait(delay);
+ });
+
+ it('Create new visualization and add to panel', () => {
+ cy.get('.euiButton__text').contains('Add visualization').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Create new visualization').click();
+ cy.wait(delay * 3);
+ cy.url().should('match', new RegExp('(.*)#/event_analytics/explorer'));
+ cy.get('[id^=autocomplete-textarea]').type(PPL_VISUALIZATIONS[2]);
+ cy.get('.euiButton__text').contains('Refresh').click();
+
+ supressResizeObserverIssue();
+ cy.get('button[id="main-content-vis"]').contains('Visualizations').click();
+ cy.wait(delay * 2);
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveComboBox"]').type(TEST_PANEL);
+ cy.get(`input[value="${TEST_PANEL}"]`).click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(PPL_VISUALIZATIONS_NAMES[2]);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ moveToTestPanel();
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[1]).should('exist');
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[2]).should('exist');
+ });
+
+ it('Move to test panel and check visualization edit button', () => {
+ moveToTestPanel();
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[0]).should('exist');
+ cy.get('button[aria-label="actionMenuButton"]').eq(0).click();
+ supressResizeObserverIssue();
+ cy.get('.euiContextMenu__itemLayout > .euiContextMenuItem__text').contains('Edit').click();
+ cy.wait(delay * 3);
+ cy.url().should('match', new RegExp('(.*)#/event_analytics/explorer'));
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]')
+ .focus()
+ .clear()
+ .type(NEW_VISUALIZATION_NAME);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('.euiToastHeader__title').contains('successfully').should('exist');
+ moveToTestPanel();
+ cy.get('h5').contains(NEW_VISUALIZATION_NAME).should('exist');
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[1]).should('exist');
+ cy.get('h5').contains(PPL_VISUALIZATIONS_NAMES[2]).should('exist');
+ });
+});
+
+describe('Add samples and clean up all test data', () => {
+ it('Add sample data', () => {
+ moveToPanelHome();
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Add samples').click();
+ cy.wait(delay);
+ cy.get('.euiModalHeader__title[data-test-subj="confirmModalTitleText"]')
+ .contains('Add samples')
+ .should('exist');
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Yes').click();
+ cy.wait(delay * 5);
+ cy.get('.euiTableCellContent').contains(SAMPLE_PANEL).should('exist');
+ cy.wait(delay);
+ });
+
+ it('Validate sample data', () => {
+ moveToPanelHome();
+ cy.get('.euiTableCellContent').contains(SAMPLE_PANEL).click();
+ cy.wait(delay * 3);
+ cy.get('h1').contains(SAMPLE_PANEL).should('exist');
+ cy.wait(delay);
+ SAMPLE_VISUALIZATIONS_NAMES.forEach((vizName) =>
+ cy.get('h5').contains(vizName).should('exist')
+ );
+ cy.wait(delay);
+ });
+
+ it('Delete visualizations from event analytics', () => {
+ moveToEventsHome();
+ cy.get('[data-test-subj="tablePaginationPopoverButton"]').click();
+ cy.get('.euiContextMenuItem__text').contains('50 rows').click();
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+ cy.wait(delay);
+ cy.get('.euiTextAlign').contains('No Queries or Visualizations').should('exist');
+ });
+
+ it('Deletes test panel', () => {
+ moveToPanelHome();
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('.euiButton__text').contains('Actions').click();
+ cy.wait(delay);
+ cy.get('.euiContextMenuItem__text').contains('Delete').click();
+ cy.wait(delay);
+
+ cy.get('button.euiButton--danger').should('be.disabled');
+
+ cy.get('input.euiFieldText[placeholder="delete"]').type('delete');
+ cy.get('button.euiButton--danger').should('not.be.disabled');
+ cy.get('.euiButton__text').contains('Delete').click();
+
+ cy.get('.euiTextAlign').contains('No Operational Panels').should('exist');
+ });
+});
diff --git a/.cypress/integration/dashboard.spec.js b/dashboards-observability/.cypress/integration/4_trace_analytics_dashboard.spec.js
similarity index 59%
rename from .cypress/integration/dashboard.spec.js
rename to dashboards-observability/.cypress/integration/4_trace_analytics_dashboard.spec.js
index 0f8e6841b..5512635ca 100644
--- a/.cypress/integration/dashboard.spec.js
+++ b/dashboards-observability/.cypress/integration/4_trace_analytics_dashboard.spec.js
@@ -1,36 +1,73 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
///
-import { delay, setTimeFilter } from '../utils/constants';
+import { testDataSet, delay, setTimeFilter } from '../utils/constants';
+
+describe('Dump test data', () => {
+ it('Indexes test data', () => {
+ const dumpDataSet = (mapping_url, data_url, index) => {
+ cy.request({
+ method: 'POST',
+ failOnStatusCode: false,
+ url: 'api/console/proxy',
+ headers: {
+ 'content-type': 'application/json;charset=UTF-8',
+ 'osd-xsrf': true,
+ },
+ qs: {
+ path: `${index}`,
+ method: 'PUT',
+ },
+ });
+
+ cy.request(mapping_url).then((response) => {
+ cy.request({
+ method: 'POST',
+ form: true,
+ url: 'api/console/proxy',
+ headers: {
+ 'content-type': 'application/json;charset=UTF-8',
+ 'osd-xsrf': true,
+ },
+ qs: {
+ path: `${index}/_mapping`,
+ method: 'POST',
+ },
+ body: response.body,
+ });
+ });
+
+ cy.request(data_url).then((response) => {
+ cy.request({
+ method: 'POST',
+ form: true,
+ url: 'api/console/proxy',
+ headers: {
+ 'content-type': 'application/json;charset=UTF-8',
+ 'osd-xsrf': true,
+ },
+ qs: {
+ path: `${index}/_bulk`,
+ method: 'POST',
+ },
+ body: response.body,
+ });
+ });
+ };
+
+ testDataSet.forEach(({ mapping_url, data_url, index }) =>
+ dumpDataSet(mapping_url, data_url, index)
+ );
+ });
+});
describe('Testing dashboard table empty state', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/dashboard', {
+ cy.visit('app/observability-dashboards#/trace_analytics/home', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -46,7 +83,7 @@ describe('Testing dashboard table empty state', () => {
describe('Testing dashboard table', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/dashboard', {
+ cy.visit('app/observability-dashboards#/trace_analytics/home', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -61,6 +98,18 @@ describe('Testing dashboard table', () => {
cy.contains('7.14%').should('exist');
});
+ it('Has working breadcrumbs', () => {
+ cy.get('.euiBreadcrumb').contains('Dashboard').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Dashboard').should('exist');
+ cy.get('.euiBreadcrumb').contains('Trace analytics').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Dashboard').should('exist');
+ cy.get('.euiBreadcrumb').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+
it('Adds the percentile filters', () => {
cy.contains(' >= 95 percentile').click({ force: true });
cy.wait(delay);
@@ -96,7 +145,7 @@ describe('Testing dashboard table', () => {
cy.contains(' (13)').should('exist');
cy.contains('client_create_order').should('exist');
- cy.get('.euiSideNavItemButton__label').contains('Dashboard').click();
+ cy.get('.euiSideNavItemButton__label').contains('Trace analytics').click();
cy.wait(delay);
cy.contains('client_create_order').should('exist');
@@ -105,7 +154,7 @@ describe('Testing dashboard table', () => {
describe('Testing plots', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/dashboard', {
+ cy.visit('app/observability-dashboards#/trace_analytics/home', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
diff --git a/.cypress/integration/services.spec.js b/dashboards-observability/.cypress/integration/5_trace_analytics_services.spec.js
similarity index 71%
rename from .cypress/integration/services.spec.js
rename to dashboards-observability/.cypress/integration/5_trace_analytics_services.spec.js
index fade548ff..638eac65f 100644
--- a/.cypress/integration/services.spec.js
+++ b/dashboards-observability/.cypress/integration/5_trace_analytics_services.spec.js
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
///
@@ -30,7 +9,7 @@ import { delay, SERVICE_NAME, setTimeFilter } from '../utils/constants';
describe('Testing services table empty state', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/services', {
+ cy.visit('app/observability-dashboards#/trace_analytics/services', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -46,7 +25,7 @@ describe('Testing services table empty state', () => {
describe('Testing services table', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/services', {
+ cy.visit('app/observability-dashboards#/trace_analytics/services', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -77,7 +56,7 @@ describe('Testing service view empty state', () => {
if (err.message.includes('ResizeObserver loop'))
return false;
});
- cy.visit(`app/trace-analytics-dashboards#/services/${SERVICE_NAME}`, {
+ cy.visit(`app/observability-dashboards#/trace_analytics/services/${SERVICE_NAME}`, {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -99,7 +78,7 @@ describe('Testing service view', () => {
if (err.message.includes('ResizeObserver loop'))
return false;
});
- cy.visit(`app/trace-analytics-dashboards#/services/${SERVICE_NAME}`, {
+ cy.visit(`app/observability-dashboards#/trace_analytics/services/${SERVICE_NAME}`, {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -108,12 +87,27 @@ describe('Testing service view', () => {
});
it('Renders service view', () => {
- cy.get('h2.euiTitle').contains('frontend-client').should('exist');
+ cy.get('h2.euiTitle').contains(SERVICE_NAME).should('exist');
cy.contains('178.6').should('exist');
cy.contains('3.57%').should('exist');
cy.get('div.vis-network').should('exist');
});
+ it('Has working breadcrumbs', () => {
+ cy.get('.euiBreadcrumb').contains(SERVICE_NAME).click();
+ cy.wait(delay);
+ cy.get('h2.euiTitle').contains(SERVICE_NAME).should('exist');
+ cy.get('.euiBreadcrumb').contains('Services').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Services').should('exist');
+ cy.get('.euiBreadcrumb').contains('Trace analytics').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Dashboard').should('exist');
+ cy.get('.euiBreadcrumb').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+
it('Renders spans data grid, flyout, filters', () => {
cy.get('button[data-datagrid-interactable="true"]').eq(0).click({ force: true });
cy.wait(delay);
@@ -124,6 +118,7 @@ describe('Testing service view', () => {
cy.wait(delay);
cy.get('.euiBadge__text').contains('spanId: ').should('exist');
+ cy.get('[data-test-subj="euiFlyoutCloseButton"]').click({ force: true });
cy.contains('Spans (1)').should('exist');
});
});
diff --git a/.cypress/integration/traces.spec.js b/dashboards-observability/.cypress/integration/6_trace_analytics_traces.spec.js
similarity index 69%
rename from .cypress/integration/traces.spec.js
rename to dashboards-observability/.cypress/integration/6_trace_analytics_traces.spec.js
index c294e75e0..2f96fab54 100644
--- a/.cypress/integration/traces.spec.js
+++ b/dashboards-observability/.cypress/integration/6_trace_analytics_traces.spec.js
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
///
@@ -30,7 +9,7 @@ import { delay, setTimeFilter, SPAN_ID, TRACE_ID } from '../utils/constants';
describe('Testing traces table empty state', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/traces', {
+ cy.visit('app/observability-dashboards#/trace_analytics/traces', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -46,7 +25,7 @@ describe('Testing traces table empty state', () => {
describe('Testing traces table', () => {
beforeEach(() => {
- cy.visit('app/trace-analytics-dashboards#/traces', {
+ cy.visit('app/observability-dashboards#/trace_analytics/traces', {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -66,6 +45,12 @@ describe('Testing traces table', () => {
cy.contains('-').should('exist');
});
+ it('Sorts the traces table', () => {
+ cy.get('.euiTableRow').first().contains('-').should('exist');
+ cy.get('.euiTableCellContent').contains('Trace group').click();
+ cy.get('.euiTableRow').first().contains('/%2A%2A').should('exist');
+ });
+
it('Searches correctly', () => {
cy.get('input[type="search"]').focus().type(`${TRACE_ID}{enter}`);
cy.get('.euiButton__text').contains('Refresh').click();
@@ -77,7 +62,7 @@ describe('Testing traces table', () => {
describe('Testing trace view', () => {
beforeEach(() => {
- cy.visit(`app/trace-analytics-dashboards#/traces/${TRACE_ID}`, {
+ cy.visit(`app/observability-dashboards#/trace_analytics/traces/${TRACE_ID}`, {
onBeforeLoad: (win) => {
win.sessionStorage.clear();
},
@@ -91,11 +76,26 @@ describe('Testing trace view', () => {
cy.contains('03/25/2021 10:21:22').should('exist');
cy.get('h2.euiTitle').contains(TRACE_ID).should('exist');
- cy.get('div.js-plotly-plot').should('have.length', 2);
+ cy.get('div.js-plotly-plot').should('have.length.gte', 2);
cy.get('text[data-unformatted="database mysql.APM "]').should('exist');
cy.contains(`"${SPAN_ID}"`).should('exist');
});
+ it('Has working breadcrumbs', () => {
+ cy.get('.euiBreadcrumb').contains(TRACE_ID).click();
+ cy.wait(delay);
+ cy.get('h2.euiTitle').contains(TRACE_ID).should('exist');
+ cy.get('.euiBreadcrumb').contains('Traces').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Traces').should('exist');
+ cy.get('.euiBreadcrumb').contains('Trace analytics').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Dashboard').should('exist');
+ cy.get('.euiBreadcrumb').contains('Observability').click();
+ cy.wait(delay);
+ cy.get('.euiTitle').contains('Event analytics').should('exist');
+ });
+
it('Renders data grid, flyout and filters', () => {
cy.get('.euiToggle__input[title="Span list"]').click({ force: true });
cy.contains('2 columns hidden').should('exist');
diff --git a/dashboards-observability/.cypress/integration/7_app_analytics.spec.js b/dashboards-observability/.cypress/integration/7_app_analytics.spec.js
new file mode 100644
index 000000000..1e8ef7c95
--- /dev/null
+++ b/dashboards-observability/.cypress/integration/7_app_analytics.spec.js
@@ -0,0 +1,597 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+///
+
+import {
+ delay,
+ moveToHomePage,
+ moveToCreatePage,
+ moveToApplication,
+ moveToEditPage,
+ changeTimeTo24,
+ expectMessageOnHover,
+ baseQuery,
+ nameOne,
+ nameTwo,
+ nameThree,
+ description,
+ service_one,
+ service_two,
+ trace_one,
+ trace_two,
+ trace_three,
+ query_one,
+ query_two,
+ availability_default,
+ visOneName,
+ visTwoName,
+ composition,
+ newName,
+ TYPING_DELAY,
+ timeoutDelay
+} from '../utils/app_constants';
+import { supressResizeObserverIssue } from '../utils/constants';
+
+describe('Creating application', () => {
+ beforeEach(() => {
+ moveToCreatePage();
+ });
+
+ it('Suggests correct autocompletion', () => {
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy.get('.aa-List').find('.aa-Item').should('have.length', 1);
+ cy.get('.aa-Item').contains('source').should('exist');
+ cy.focused().type('{enter}');
+ cy.get('.aa-List').find('.aa-Item').should('have.length', 1);
+ cy.get('.aa-Item').contains('=').should('exist');
+ cy.focused().type('{enter}');
+ cy.focused().type('opensearch');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy.get('.aa-Item').contains('opensearch_dashboards_sample_data_flights').click();
+ cy.focused().clear();
+ cy.get('.aa-List').find('.aa-Item').should('have.length', 1);
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain', 'source ');
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain', 'source = ');
+ cy.focused().type('opensearch');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy.get('.aa-Item').contains('opensearch_dashboards_sample_data_flights').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain', 'source = opensearch_dashboards_sample_data_flights ');
+ cy.focused().type('{downArrow}');
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain', 'source = opensearch_dashboards_sample_data_flights, ');
+ cy.focused().type('opensearch');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy.get('.aa-Item').contains('opensearch_dashboards_sample_data_logs').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain', 'source = opensearch_dashboards_sample_data_flights,opensearch_dashboards_sample_data_logs ');
+ });
+
+ it('Creates an application and redirects to application', () => {
+ expectMessageOnHover('createButton', 'Name is required.');
+ cy.get('[data-test-subj="nameFormRow"]').type(nameOne);
+ cy.get('[data-test-subj="descriptionFormRow"]').type('This application is for testing.');
+ expectMessageOnHover('createButton', 'Provide at least one log source, service, entity or trace group.');
+ cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="servicesEntitiesComboBox"]').click();
+ cy.focused().type('{downArrow}');
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '1');
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="createButton"]').should('not.be.disabled');
+ cy.get('[data-test-subj="createAndSetButton"]').should('be.disabled');
+ expectMessageOnHover('createAndSetButton', 'Log source is required to set availability.');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus().type(baseQuery, {delay: TYPING_DELAY});
+ cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="traceGroupsComboBox"]').scrollIntoView().type('http');
+ cy.get('.euiFilterSelectItem').contains(trace_one).trigger('click');
+ cy.get('.euiFilterSelectItem').contains(trace_two).trigger('click');
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '2');
+ cy.get('[data-test-subj="createButton"]').should('not.be.disabled');
+ cy.get('[data-test-subj="createButton"]').click();
+ cy.wait(delay * 3);
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameOne);
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.get('[data-test-subj="addFirstVisualizationText"]').should('exist');
+ });
+
+ it('Redirects to home page on cancel', () => {
+ cy.get('[data-test-subj="cancelCreateButton"]').contains('Cancel').click();
+ cy.get('[data-test-subj="applicationHomePageTitle"]').should('exist');
+ });
+
+ it('Saves current input on reload', () => {
+ cy.get('[data-test-subj="nameFormRow"]').type(nameOne);
+ cy.get('[data-test-subj="descriptionFormRow"]').type(description);
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy
+ .get('[data-test-subj="searchAutocompleteTextArea"]')
+ .focus()
+ .type(baseQuery, {delay: TYPING_DELAY});
+ cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="servicesEntitiesComboBox"]').scrollIntoView();
+ cy.get('[data-test-subj="servicesEntitiesComboBox"]').trigger('mouseover').click();
+ cy.get('.euiFilterSelectItem').contains(service_one).click({ force: true });
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '1');
+ cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="traceGroupsComboBox"]').scrollIntoView().type('http');
+ cy.get('.euiFilterSelectItem').contains(trace_one).trigger('click');
+ cy.get('.euiFilterSelectItem').contains(trace_two).trigger('click');
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '2');
+ cy.reload();
+ cy.wait(delay);
+ cy.get('[data-test-subj="nameFormRow"]').find('.euiFieldText').should('contain.value', nameOne);
+ cy.get('[data-test-subj="descriptionFormRow"]').find('.euiFieldText').should('contain.value', description);
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain.value', baseQuery);
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '1');
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '2');
+ });
+
+ it('Shows clear modals before clearing', () => {
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="clearLogSourceButton"]').should('be.disabled');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus().type(baseQuery, {delay: TYPING_DELAY});
+ cy.get('[data-test-subj="clearLogSourceButton"]').click();
+ cy.get('.euiButton--danger').contains('Clear').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain.value', '');
+ cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="servicesEntitiesComboBox"]').trigger('mouseover').click();
+ cy.get('.euiFilterSelectItem').contains(service_one).trigger('click');
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '1');
+ cy.get('[data-test-subj="clearServicesEntitiesButton"]').click();
+ cy.get('.euiButton--danger').contains('Clear all').click();
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '0');
+ cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="traceGroupsComboBox"]').scrollIntoView().type('http');
+ cy.get('.euiFilterSelectItem').contains(trace_one).trigger('click');
+ cy.get('.euiFilterSelectItem').contains(trace_two).trigger('click');
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '2');
+ cy.get('[data-test-subj="clearTraceGroupsButton"]').click();
+ cy.get('.euiButton--danger').contains('Clear all').click();
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '0');
+ });
+
+ it('Saves time range for each application', () => {
+ cy.get('[data-test-subj="nameFormRow"]').type(nameTwo);
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus().type(baseQuery, {delay: TYPING_DELAY});
+ cy.get('[data-test-subj="createButton"]').should('not.be.disabled');
+ cy.get('[data-test-subj="createButton"]').click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameTwo);
+ changeTimeTo24('weeks');
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 weeks');
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.wait(delay);
+ cy.get(`[data-test-subj="${nameOne}ApplicationLink"]`).click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameOne);
+ changeTimeTo24('months');
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get(`[data-test-subj="${nameTwo}ApplicationLink"]`).click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameTwo);
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 weeks');
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get(`[data-test-subj="${nameOne}ApplicationLink"]`).click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameOne);
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ });
+});
+
+describe('Setting availability', () => {
+ it('Redirects to set availability at three entry points', () => {
+ moveToCreatePage();
+ cy.get('[data-test-subj="nameFormRow"]').type(nameThree);
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus();
+ cy.focused().type('source = ', { delay: TYPING_DELAY });
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="createAndSetButton"]').click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameThree);
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get('[data-test-subj="setAvailabilityHomePageLink"]').first().click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameThree);
+ cy.get('.euiTab-isSelected[id="app-analytics-log"]').should('exist', { timeout: timeoutDelay });
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain.value', availability_default);
+ cy.get('[id="explorerPlotComponent"]').should('exist');
+ cy.get('.euiTab-isSelected[id="availability-panel"]').should('exist');
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get(`[data-test-subj="${nameThree}ApplicationLink"]`).click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameThree);
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.get('[data-test-subj="setAvailabilityConfigLink"]').click();
+ cy.get('.euiTab-isSelected[id="app-analytics-log"]').should('exist', { timeout: timeoutDelay });
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('contain.value', availability_default);
+ cy.get('[id="explorerPlotComponent"]').should('exist');
+ cy.get('.euiTab-isSelected[id="availability-panel"]').should('exist');
+ });
+});
+
+describe('Viewing application', () => {
+ beforeEach(() => {
+ moveToApplication(nameOne);
+ });
+
+ it('Has working breadcrumbs', () => {
+ cy.get('.euiBreadcrumb').contains(nameOne).click();
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameOne);
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get('[data-test-subj="applicationHomePageTitle"]').should('contain', 'Applications');
+ cy.get('.euiBreadcrumb[href="observability-dashboards#/"]').click();
+ cy.get('[data-test-subj="eventHomePageTitle"]').should('contain', 'Event analytics');
+ });
+
+ it('Shares time range among tabs', () => {
+ changeTimeTo24('months');
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('[data-test-subj="app-analytics-serviceTab"]').click();
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('[data-test-subj="app-analytics-traceTab"]').click();
+ supressResizeObserverIssue();
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('[data-test-subj="app-analytics-logTab"]').click();
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ });
+
+ it('Shows latency variance in dashboards table', () => {
+ changeTimeTo24('months');
+ cy.get('[data-test-subj="dashboardTable"]').first().within(($table) => {
+ cy.get('.plot-container').should('have.length.at.least', 1);
+ })
+ });
+
+ it('Adds filter when Trace group name is clicked', () => {
+ cy.get('[data-test-subj="app-analytics-overviewTab"]').click();
+ cy.get('[data-test-subj="dashboard-table-trace-group-name-button"]').contains('client_create_order').click();
+ cy.get('.euiTableRow').should('have.length', 1, { timeout: timeoutDelay });
+ cy.get('[data-test-subj="client_create_orderFilterBadge"]').should('exist');
+ cy.get('[data-test-subj="filterBadge"]').click();
+ cy.get('[data-test-subj="deleteFilterIcon"]').click();
+ cy.get('[data-test-subj="client_create_orderFilterBadge"]').should('not.exist');
+ });
+
+ it('Opens service detail flyout when Service Name is clicked', () => {
+ cy.get('[data-test-subj="app-analytics-serviceTab"]').click();
+ cy.wait(delay);
+ cy.get('.euiLink').contains('authentication').click();
+ supressResizeObserverIssue();
+ cy.get('[data-test-subj="serviceDetailFlyoutTitle"]').should('be.visible');
+ cy.get('[data-test-subj="serviceDetailFlyout"]').within(($flyout) => {
+ cy.get('[data-test-subj="Number of connected servicesDescriptionList"]').should('contain', '3');
+ cy.get('[data-text="Error rate"]').click();
+ cy.get('.ytitle').contains('Error rate').should('exist');
+ });
+ cy.get('[data-test-subj="dataGridRowCell"] button').contains('718dc32a693c8a17').click();
+ cy.get('[data-test-subj="spanDetailFlyout"]').contains('Span detail').should('be.visible');
+ cy.get('[data-test-subj="ServiceDescriptionList"]').should('contain', 'authentication');
+ cy.get('[data-test-subj="euiFlyoutCloseButton"]').click();
+ cy.get('[data-test-subj="serviceDetailFlyout"]').should('not.be.visible');
+ cy.get('[data-test-subj="spanDetailFlyout"]').should('not.be.visible');
+ });
+
+ it('Opens trace detail flyout when Trace ID is clicked', () => {
+ cy.get('[data-test-subj="app-analytics-traceTab"]').click();
+ supressResizeObserverIssue();
+ cy.wait(delay);
+ cy.get('[title="03f9c770db5ee2f1caac0afc36db49ba"]').click();
+ cy.get('[data-test-subj="traceDetailFlyoutTitle"]').should('be.visible');
+ cy.get('[data-test-subj="traceDetailFlyout"]').within(($flyout) => {
+ cy.get('[data-test-subj="LatencyDescriptionList"]').should('contain', '224.99');
+ });
+ cy.get('[data-test-subj="euiFlyoutCloseButton"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="traceDetailFlyout"]').should('not.be.visible');
+ cy.get('[title="03f9c770db5ee2f1caac0afc36db49ba"]').click();
+ cy.get('[aria-label="Span list"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="dataGridRowCell"] button').contains('d67c5bb617ba9203').click();
+ cy.get('[data-test-subj="spanDetailFlyout"]').should('be.visible');
+ cy.get('[data-test-subj="euiFlyoutCloseButton"]').click();
+ cy.get('[data-test-subj="spanDetailFlyout"]').should('not.be.visible');
+ });
+
+ it('Opens span detail flyout when Span ID is clicked', () => {
+ cy.get('[data-test-subj="app-analytics-traceTab"]').click();
+ supressResizeObserverIssue();
+ cy.wait(delay);
+ cy.get('[data-test-subj="dataGridRowCell"]').contains('5ff3516909562c60').click();
+ cy.get('[data-test-subj="spanDetailFlyout"]').should('be.visible');
+ cy.get('[data-test-subj="spanDetailFlyout"]').within(($flyout) => {
+ cy.get('[data-test-subj="OperationDescriptionList"]').should('contain', 'HTTP GET');
+ });
+ cy.get('.euiText').contains('order').click();
+ cy.get('[aria-label="span-flyout-filter-icon"]').click();
+ cy.focused().blur();
+ cy.get('[data-test-subj="euiFlyoutCloseButton"]').click();
+ cy.get('[data-test-subj="filterBadge"][title="serviceName: order"]').should('exist');
+ cy.get('[aria-label="Remove filter"]').click();
+ cy.get('[data-test-subj="filterBadge"][title="serviceName: order"]').should('not.exist');
+ });
+
+ it('Shows base query', () => {
+ cy.get('[data-test-subj="app-analytics-logTab"]').click();
+ cy.get('.euiBadge[title="Base Query"]').should('exist');
+ cy.get('.euiBadge[title="Base Query"]').trigger('mouseover');
+ cy.get('.euiToolTipPopover').contains('source = opensearch_dashboards_sample_data_flights').should('exist');
+ });
+
+ it('Saves visualization #1 to panel', () => {
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.get('[data-test-subj="addVisualizationButton"]').first().click();
+ cy.wait(delay);
+ cy.get('[id="explorerPlotComponent"]').should('exist');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').click();
+ cy.get('.aa-List').find('.aa-Item').should('have.length', 11);
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus().type(query_one, {delay: TYPING_DELAY});
+ changeTimeTo24('months');
+ cy.wait(delay * 2);
+ cy.get('[data-test-subj="main-content-visTab"]').click();
+ supressResizeObserverIssue();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').click().type(visOneName);
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="Flights to VeniceVisualizationPanel"]').should('exist');
+ cy.get('[id="explorerPlotComponent"]').should('exist');
+ cy.get('[class="trace bars"]').should('exist');
+ });
+
+ it('Adds availability level to visualization #1', () => {
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.get('[aria-label="actionMenuButton"]').click();
+ cy.get('[data-test-subj="editVizContextMenuItem"]').click();
+ supressResizeObserverIssue();
+ cy.get('[data-test-subj="superDatePickerShowDatesButton"]').should('contain', 'Last 24 months');
+ cy.get('.euiTab[id="availability-panel"]').click();
+ cy.get('[title="Bar"]').click();
+ cy.focused().type('{downArrow}');
+ cy.focused().type('{enter}');
+ cy.get('[data-test-subj="addAvailabilityButton"]').click();
+ cy.get('[data-test-subj="colorPickerAnchor"]').click();
+ cy.get('[aria-label="Select #54B399 as the color"]').click();
+ cy.get('[data-test-subj="nameFieldText"]').click().type('Available');
+ cy.get('option').contains('≥').should('exist');
+ cy.get('option').contains('≤').should('exist');
+ cy.get('option').contains('>').should('exist');
+ cy.get('option').contains('<').should('exist');
+ cy.get('option').contains('=').should('exist');
+ cy.get('option').contains('≠').should('exist');
+ cy.get('[data-test-subj="expressionSelect"]').select('>');
+ cy.get('[data-test-subj="valueFieldNumber"]').clear().type('0.5');
+ cy.get('[data-test-subj="visualizeEditorRenderButton"]').click();
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.get('[id="explorerPlotComponent"]').should('exist');
+ cy.get('[class="lines"]').should('exist');
+ cy.get('.textpoint').contains('Available').should('exist');
+ cy.get('.euiBreadcrumb[href="#/application_analytics"]').click();
+ cy.get('[data-test-subj="AvailableAvailabilityBadge"]').should('contain', 'Available');
+ cy.get('[data-test-subj="AvailableAvailabilityBadge"][style="background-color: rgb(84, 179, 153); color: rgb(0, 0, 0);"]').should('exist');
+ });
+
+ it('Saves visualization #2 to panel with availability level', () => {
+ changeTimeTo24('months');
+ cy.get('[data-test-subj="app-analytics-logTab"]').click();
+ cy.get('[id="explorerPlotComponent"]', { timeout: timeoutDelay }).should('exist');
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').focus().type(query_two, {delay: TYPING_DELAY});
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="main-content-visTab"]').click();
+ supressResizeObserverIssue();
+ cy.get('.euiTab[id="availability-panel"]').click();
+ cy.get('[title="Bar"]').click();
+ cy.focused().type('{downArrow}');
+ cy.focused().type('{enter}');
+ cy.wait(delay);
+ cy.get('[data-test-subj="addAvailabilityButton"]').click();
+ cy.get('[data-test-subj="colorPickerAnchor"]').click();
+ cy.get('[aria-label="Select #9170B8 as the color"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="nameFieldText"]').click().type('Super');
+ cy.get('[data-test-subj="expressionSelect"]').select('<');
+ cy.get('[data-test-subj="valueFieldNumber"]').clear().type('5.5');
+ cy.get('[data-test-subj="visualizeEditorRenderButton"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="addAvailabilityButton"]').click();
+ cy.get('[data-test-subj="colorPickerAnchor"]').first().click();
+ cy.get('[aria-label="Select #CA8EAE as the color"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="nameFieldText"]').first().click().type('Cool');
+ cy.get('[data-test-subj="expressionSelect"]').first().select('>');
+ cy.get('[data-test-subj="valueFieldNumber"]').first().clear().type('0');
+ cy.get('[data-test-subj="visualizeEditorRenderButton"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
+ cy.get('[data-test-subj="eventExplorer__querySaveName"]').click().type(visTwoName);
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="app-analytics-panelTab"]').click();
+ cy.wait(delay);
+ cy.get('[id="explorerPlotComponent"]').should('have.length', 2);
+ moveToHomePage();
+ cy.get('[data-test-subj="SuperAvailabilityBadge"][style="background-color: rgb(145, 112, 184); color: rgb(0, 0, 0);"]').should('contain', 'Super');
+ });
+
+ it('Configuration tab shows details', () => {
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="configBaseQueryCode"]').should('contain', baseQuery);
+ cy.get('[aria-label="List of services and entities"]').find('li').should('have.length', 1);
+ cy.get('[aria-label="List of trace groups"]').find('li').should('have.length', 2);
+ cy.get('option').should('have.length', 2);
+ });
+
+
+ it('Changes availability visualization', () => {
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.wait(delay);
+ cy.get('select').select(visOneName);
+ cy.wait(delay);
+ moveToHomePage();
+ cy.get('[data-test-subj="AvailableAvailabilityBadge"][style="background-color: rgb(84, 179, 153); color: rgb(0, 0, 0);"]').should('contain', 'Available');
+ moveToApplication(nameOne);
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.wait(delay);
+ cy.get('select').find('option:selected').should('have.text', visOneName);
+ })
+});
+
+describe('Separate from other plugins', () => {
+ it('Hides application visualizations in Event Analytics', () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics`);
+ cy.wait(delay * 3);
+ // When there are saved queries or visualizations there are two buttons
+ cy.get('body').then(($body) => {
+ if ($body.find('.euiButton').length == 2) {
+ cy.get('input.euiFieldSearch').type(visOneName, {delay: TYPING_DELAY});
+ cy.wait(delay);
+ cy.get('.euiTableCellContent__text').contains('No items found').should('exist');
+ cy.get('input.euiFieldSearch').clear().type(visTwoName, {delay: TYPING_DELAY});
+ cy.wait(delay);
+ cy.get('.euiTableCellContent__text').contains('No items found').should('exist');
+ cy.get('[class="euiFormControlLayoutClearButton"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="tablePaginationPopoverButton"]').click();
+ cy.get('.euiContextMenuItem__text').contains('50 rows').click();
+ cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventHomeAction"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="eventHomeAction__delete"]').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="popoverModal__deleteButton"]').should('be.disabled');
+ cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
+ cy.get('[data-test-subj="popoverModal__deleteButton"]').should('not.be.disabled');
+ cy.get('[data-test-subj="popoverModal__deleteButton"]').click();
+ cy.wait(delay);
+ }
+ })
+ });
+
+ it('Hides application visualizations in Operational Panels', () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
+ );
+ cy.get('[data-test-subj="operationalPanelsActionsButton"]', { timeout: timeoutDelay }).click();
+ cy.get('[data-test-subj="addSampleContextMenuItem"]', { timeout: timeoutDelay }).click();
+ cy.get('[data-test-subj="confirmModalConfirmButton"]', { timeout: timeoutDelay }).click();
+ cy.wait(delay * 2);
+ cy.get('.euiLink').contains('[Logs] Web traffic Panel').first().click();
+ cy.wait(delay * 2);
+ cy.get('[data-test-subj="addVisualizationButton"]').click();
+ cy.get('.euiContextMenuItem__text').contains('Select existing visualization').click();
+ cy.get('option').contains(visOneName).should('not.exist');
+ cy.get('option').contains(visTwoName).should('not.exist');
+ });
+
+ it('Hides application panels in Operational Panels', () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
+ );
+ cy.get('[data-test-subj="operationalPanelSearchBar"]', { timeout: timeoutDelay }).type(`${nameOne}'s Panel`, {delay: TYPING_DELAY});
+ cy.get('.euiTableCellContent__text').contains('No items found').should('exist');
+ cy.get('.euiFormControlLayoutClearButton').click();
+ cy.get('[data-test-subj="operationalPanelSearchBar"]').type('[Logs] Web traffic Panel', {delay: TYPING_DELAY});
+ cy.get('.euiTableRow').first().within(($row) => {
+ cy.get('.euiCheckbox').click();
+ });
+ cy.get('[data-test-subj="operationalPanelsActionsButton"]', { timeout: timeoutDelay }).click();
+ cy.get('[data-test-subj="deleteContextMenuItem"]', { timeout: timeoutDelay }).click();
+ cy.get('[data-test-subj="popoverModal__deleteTextInput"]', { timeout: timeoutDelay }).type('delete');
+ cy.get('[data-test-subj="popoverModal__deleteButton"]', { timeout: timeoutDelay }).should('not.be.disabled');
+ cy.get('[data-test-subj="popoverModal__deleteButton"]', { timeout: timeoutDelay }).click();
+ });
+});
+
+describe('Editing application', () => {
+ beforeEach(() => {
+ moveToEditPage();
+ });
+
+ it('Redirects to application after saving changes', () => {
+ cy.get('[data-test-subj="logSourceAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="searchAutocompleteTextArea"]').should('be.disabled');
+ cy.get('[data-test-subj="servicesEntitiesAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="servicesEntitiesComboBox"]').click();
+ cy.get('.euiFilterSelectItem').contains(service_two).click();
+ cy.get('[data-test-subj="servicesEntitiesCountBadge"]').should('contain', '2');
+ cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="comboBoxToggleListButton"]').eq(1).click();
+ cy.get('.euiFilterSelectItem').contains(trace_three).trigger('click');
+ cy.get('[data-test-subj="traceGroupsCountBadge"]').should('contain', '3');
+ cy.get('[data-test-subj="traceGroupsAccordion"]').trigger('mouseover').click();
+ cy.get('[data-test-subj="createButton"]').click();
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.get('[data-test-subj="configBaseQueryCode"]').should('contain', baseQuery);
+ cy.get('[aria-label="List of services and entities"]').find('li').should('have.length', 2);
+ cy.get('[aria-label="List of trace groups"]').find('li').should('have.length', 3);
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', nameOne);
+ });
+});
+
+describe('Application Analytics home page', () => {
+ beforeEach(() => {
+ moveToHomePage();
+ })
+
+ it('Show correct information in table', () => {
+ cy.get(`[data-test-subj="${nameOne}ApplicationLink"]`).should('exist');
+ cy.get('[data-test-subj="appAnalytics__compositionColumn"]').should('contain', composition);
+ cy.get('[data-test-subj="AvailableAvailabilityBadge"][style="background-color: rgb(84, 179, 153); color: rgb(0, 0, 0);"]').should('contain', 'Available')
+ });
+
+ it('Renames application', () => {
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('[data-test-subj="renameApplicationContextMenuItem"]').should('be.disabled');
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('.euiTableRow').first().within(($row) => {
+ cy.get('.euiCheckbox').click();
+ });
+ cy.wait(delay);
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('[data-test-subj="renameApplicationContextMenuItem"]').click();
+ cy.get('[data-test-subj="customModalFieldText"]').clear().focus().type(newName);
+ cy.get('[data-test-subj="runModalButton"]').click();
+ cy.wait(delay);
+ cy.get('.euiToast').contains(`Application successfully renamed to "${newName}"`);
+ cy.get('.euiTableRow').first().within(($row) => {
+ cy.get('.euiLink').contains(newName).should('exist');
+ });
+ });
+
+
+ it('Deletes application', () => {
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('[data-test-subj="deleteApplicationContextMenuItem"]').should('exist');
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('.euiTableRow').first().within(($row) => {
+ cy.get('.euiCheckbox').click();
+ });
+ cy.get('.euiTableRow').eq(1).within(($row) => {
+ cy.get('.euiCheckbox').click();
+ });
+ cy.get('.euiTableRow').eq(2).within(($row) => {
+ cy.get('.euiCheckbox').click();
+ });
+ cy.get('[data-test-subj="appAnalyticsActionsButton"]').click();
+ cy.get('[data-test-subj="deleteApplicationContextMenuItem"]').click();
+ cy.get('[data-test-subj="popoverModal__deleteTextInput"]').type('delete');
+ cy.get('[data-test-subj="popoverModal__deleteButton"').click();
+ cy.wait(delay);
+ cy.get('.euiToast').contains(`Applications successfully deleted!`);
+ cy.get(`[data-test-subj="${newName}ApplicationLink"]`).should('not.exist');
+ });
+});
diff --git a/dashboards-observability/.cypress/plugins/index.js b/dashboards-observability/.cypress/plugins/index.js
new file mode 100644
index 000000000..8ac1f1066
--- /dev/null
+++ b/dashboards-observability/.cypress/plugins/index.js
@@ -0,0 +1,26 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+///
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+/**
+ * @type {Cypress.PluginConfig}
+ */
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+}
diff --git a/dashboards-observability/.cypress/support/commands.js b/dashboards-observability/.cypress/support/commands.js
new file mode 100644
index 000000000..fd4a5a063
--- /dev/null
+++ b/dashboards-observability/.cypress/support/commands.js
@@ -0,0 +1,71 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
+
+const { ADMIN_AUTH } = require('./constants');
+
+Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
+ // Add the basic auth header when security enabled in the OpenSearch cluster
+ // https://github.com/cypress-io/cypress/issues/1288
+ if (Cypress.env('security_enabled')) {
+ if (options) {
+ options.auth = ADMIN_AUTH;
+ } else {
+ options = { auth: ADMIN_AUTH };
+ }
+ // Add query parameters - select the default OpenSearch Dashboards tenant
+ options.qs = { security_tenant: 'private' };
+ return originalFn(url, options);
+ } else {
+ return originalFn(url, options);
+ }
+});
+
+// Be able to add default options to cy.request(), https://github.com/cypress-io/cypress/issues/726
+Cypress.Commands.overwrite('request', (originalFn, ...args) => {
+ let defaults = {};
+ // Add the basic authentication header when security enabled in the OpenSearch cluster
+ if (Cypress.env('security_enabled')) {
+ defaults.auth = ADMIN_AUTH;
+ }
+
+ let options = {};
+ if (typeof args[0] === 'object' && args[0] !== null) {
+ options = Object.assign({}, args[0]);
+ } else if (args.length === 1) {
+ [options.url] = args;
+ } else if (args.length === 2) {
+ [options.method, options.url] = args;
+ } else if (args.length === 3) {
+ [options.method, options.url, options.body] = args;
+ }
+
+ return originalFn(Object.assign({}, defaults, options));
+});
diff --git a/dashboards-observability/.cypress/support/constants.js b/dashboards-observability/.cypress/support/constants.js
new file mode 100644
index 000000000..d7978c222
--- /dev/null
+++ b/dashboards-observability/.cypress/support/constants.js
@@ -0,0 +1,10 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const ADMIN_AUTH = {
+ username: 'admin',
+ password: 'admin',
+};
+
diff --git a/dashboards-observability/.cypress/support/index.js b/dashboards-observability/.cypress/support/index.js
new file mode 100644
index 000000000..6b25b7b27
--- /dev/null
+++ b/dashboards-observability/.cypress/support/index.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+// Switch the base URL of OpenSearch when security enabled in the cluster
+if (Cypress.env('security_enabled')) {
+ Cypress.env('opensearch', 'https://localhost:9200');
+}
+
diff --git a/dashboards-observability/.cypress/tsconfig.json b/dashboards-observability/.cypress/tsconfig.json
new file mode 100644
index 000000000..36de33dee
--- /dev/null
+++ b/dashboards-observability/.cypress/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "allowJs": true,
+ "baseUrl": "../node_modules",
+ "types": ["cypress"]
+ },
+ "include": ["**/*.*"]
+}
diff --git a/dashboards-observability/.cypress/utils/app_constants.js b/dashboards-observability/.cypress/utils/app_constants.js
new file mode 100644
index 000000000..f2a4e9c6a
--- /dev/null
+++ b/dashboards-observability/.cypress/utils/app_constants.js
@@ -0,0 +1,88 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { supressResizeObserverIssue } from './constants';
+
+export const delay = 1000;
+export const timeoutDelay = 30000;
+export const TYPING_DELAY = 500;
+
+export const moveToHomePage = () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/application_analytics/`);
+ cy.wait(delay * 3);
+ cy.get('.euiTitle').contains('Applications').should('exist');
+};
+
+export const moveToCreatePage = () => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/application_analytics/`);
+ cy.get('.euiButton[href="#/application_analytics/create"]').eq(0).click();
+ supressResizeObserverIssue();
+ cy.get('[data-test-subj="createPageTitle"]').should('contain', 'Create application');
+};
+
+export const moveToApplication = (name) => {
+ cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/application_analytics/`);
+ cy.wait(delay * 6);
+ cy.get(`[data-test-subj="${name}ApplicationLink"]`).click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="applicationTitle"]').should('contain', name);
+ changeTimeTo24('years');
+};
+
+export const moveToEditPage = () => {
+ moveToApplication(nameOne);
+ cy.get('[data-test-subj="app-analytics-configTab"]').click();
+ cy.get('[data-test-subj="editApplicationButton"]').click();
+ supressResizeObserverIssue();
+ cy.wait(delay);
+ cy.get('[data-test-subj="createPageTitle"]').should('contain', 'Edit application');
+};
+
+export const changeTimeTo24 = (timeUnit) => {
+ cy.get('#QuickSelectPopover').click();
+ cy.get('[aria-label="Time unit"]').select(timeUnit);
+ cy.get('.euiButton').contains('Apply').click();
+ cy.wait(delay);
+ cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').click();
+};
+
+export const expectMessageOnHover = (button, message) => {
+ cy.get(`[data-test-subj="${button}"]`).click({ force: true });
+ cy.get('.euiToolTipPopover').contains(message).should('exist');
+};
+
+export const moveToPanelHome = () => {
+ cy.visit(
+ `${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
+ );
+ cy.wait(delay * 3);
+};
+
+export const deleteAllSavedApplications = () => {
+ moveToHomePage();
+ cy.get('[data-test-subj="checkboxSelectAll"]').click();
+ cy.get('.euiPopover').contains('Actions').click();
+ cy.get('.euiContextMenuItem').contains('Delete').click();
+ cy.get('.euiButton__text').contains('Delete').click();
+};
+
+export const uniqueId = Date.now();
+export const baseQuery = 'source = opensearch_dashboards_sample_data_flights';
+export const nameOne = `Cypress-${uniqueId}`;
+export const nameTwo = `Pine-${uniqueId}`;
+export const nameThree = `Cedar-${uniqueId}`;
+export const description = 'This is my application for cypress testing.';
+export const service_one = 'order';
+export const service_two = 'payment';
+export const trace_one = 'HTTP POST';
+export const trace_two = 'HTTP GET';
+export const trace_three = 'client_pay_order';
+export const query_one = 'where DestCityName = "Venice" | stats count() by span( timestamp , 6h )';
+export const query_two = 'where OriginCityName = "Seoul" | stats count() by span( timestamp , 6h )';
+export const availability_default = 'stats count() by span( timestamp, 1h )';
+export const visOneName = 'Flights to Venice';
+export const visTwoName = 'Flights from Seoul';
+export const composition = 'order, payment, HTTP POST, HTTP GET, client_pay_order'
+export const newName = `Monterey Cypress-${uniqueId}`;
diff --git a/dashboards-observability/.cypress/utils/constants.js b/dashboards-observability/.cypress/utils/constants.js
new file mode 100644
index 000000000..e99c97ddc
--- /dev/null
+++ b/dashboards-observability/.cypress/utils/constants.js
@@ -0,0 +1,120 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const delay = 1500;
+
+// trace analytics
+export const TRACE_ID = '8832ed6abbb2a83516461960c89af49d';
+export const SPAN_ID = 'a673bc074b438374';
+export const SERVICE_NAME = 'frontend-client';
+
+export const testDataSet = [
+ {
+ mapping_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-service-map-mappings.json',
+ data_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-service-map.json',
+ index: 'otel-v1-apm-service-map',
+ },
+ {
+ mapping_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001-mappings.json',
+ data_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001.json',
+ index: 'otel-v1-apm-span-000001',
+ },
+ {
+ mapping_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001-mappings.json',
+ data_url: 'https://raw.githubusercontent.com/opensearch-project/observability/main/dashboards-observability/.cypress/utils/otel-v1-apm-span-000002.json',
+ index: 'otel-v1-apm-span-000002',
+ },
+]
+
+export const setTimeFilter = (setEndTime = false, refresh = true) => {
+ const startTime = 'Mar 25, 2021 @ 10:00:00.000';
+ const endTime = 'Mar 25, 2021 @ 11:00:00.000';
+ cy.get('button.euiButtonEmpty[aria-label="Date quick select"]').click();
+ cy.get('.euiQuickSelect__applyButton').click();
+ cy.get('.euiSuperDatePicker__prettyFormatLink').click();
+ cy.get(
+ 'button.euiDatePopoverButton--start[data-test-subj="superDatePickerstartDatePopoverButton"]'
+ ).click();
+ cy.get('.euiTab__content').contains('Absolute').click();
+ cy.get('input[data-test-subj="superDatePickerAbsoluteDateInput"]')
+ .focus()
+ .type('{selectall}' + startTime);
+ if (setEndTime) {
+ cy.wait(delay);
+ cy.get(
+ 'button.euiDatePopoverButton--end[data-test-subj="superDatePickerendDatePopoverButton"]'
+ ).click();
+ cy.wait(delay);
+ cy.get('.euiTab__content').contains('Absolute').click();
+ cy.get('input[data-test-subj="superDatePickerAbsoluteDateInput"]')
+ .focus()
+ .type('{selectall}' + endTime);
+ }
+ if (refresh) cy.get('.euiButton__text').contains('Refresh').click();
+ cy.wait(delay);
+};
+
+// notebooks
+export const TEST_NOTEBOOK = 'Test Notebook';
+export const SAMPLE_URL = 'https://github.com/opensearch-project/sql/tree/main/sql-jdbc';
+export const MARKDOWN_TEXT = `%md
+# Heading 1
+
+#### List and links
+
+* 1
+* 2
+* [SQL JDBC](${SAMPLE_URL})
+
+---
+#### Code block
+* Explain SQL
+\`\`\`
+POST _plugins/_sql/_explain
+{
+ "query": "SELECT * FROM my-index LIMIT 50"
+}
+\`\`\`
+
+#### Table
+| a1 | b1 | c1 | d1 |
+|----|----|----|----|
+| a2 | b2 | c2 | d2 |
+| a3 | b3 | c3 | d3 |
+`
+
+export const SQL_QUERY_TEXT = `%sql
+select * from opensearch_dashboards_sample_data_flights limit 20
+`
+
+export const PPL_QUERY_TEXT = `%ppl
+source=opensearch_dashboards_sample_data_flights
+`
+
+// event analytics
+export const TEST_QUERIES = [
+ {
+ query: 'source = opensearch_dashboards_sample_data_flights'
+ },
+ {
+ query: 'source = opensearch_dashboards_sample_data_flights | stats avg(FlightDelayMin) by Carrier'
+ },
+ {
+ query: 'source = opensearch_dashboards_sample_data_logs'
+ },
+];
+
+export const TESTING_PANEL = 'Mock Testing Panels';
+export const SAVE_QUERY1 = 'Mock Flight Events Overview';
+export const SAVE_QUERY2 = 'Mock Flight count by destination';
+export const SAVE_QUERY3 = 'Mock Flight count by destination save to panel';
+export const SAVE_QUERY4 = 'Mock Flight peek';
+
+export const supressResizeObserverIssue = () => {
+ // exception is thrown on loading EuiDataGrid in cypress only, ignore for now
+ cy.on('uncaught:exception', (err, runnable) => {
+ if (err.message.includes('ResizeObserver loop')) return false;
+ });
+};
\ No newline at end of file
diff --git a/.cypress/utils/otel-v1-apm-service-map-mappings.json b/dashboards-observability/.cypress/utils/otel-v1-apm-service-map-mappings.json
similarity index 100%
rename from .cypress/utils/otel-v1-apm-service-map-mappings.json
rename to dashboards-observability/.cypress/utils/otel-v1-apm-service-map-mappings.json
diff --git a/.cypress/utils/otel-v1-apm-service-map.json b/dashboards-observability/.cypress/utils/otel-v1-apm-service-map.json
similarity index 100%
rename from .cypress/utils/otel-v1-apm-service-map.json
rename to dashboards-observability/.cypress/utils/otel-v1-apm-service-map.json
diff --git a/.cypress/utils/otel-v1-apm-span-000001-mappings.json b/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001-mappings.json
similarity index 100%
rename from .cypress/utils/otel-v1-apm-span-000001-mappings.json
rename to dashboards-observability/.cypress/utils/otel-v1-apm-span-000001-mappings.json
diff --git a/.cypress/utils/otel-v1-apm-span-000001.json b/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001.json
similarity index 52%
rename from .cypress/utils/otel-v1-apm-span-000001.json
rename to dashboards-observability/.cypress/utils/otel-v1-apm-span-000001.json
index b035da76a..1c6fcbbf7 100644
--- a/.cypress/utils/otel-v1-apm-span-000001.json
+++ b/dashboards-observability/.cypress/utils/otel-v1-apm-span-000001.json
@@ -998,971 +998,3 @@
{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"c8fff65b158a58b0","traceState":"","parentSpanId":"303b76b989099bb5","name":"cartSold","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:23:59.327906816Z","endTime":"2021-03-25T17:23:59.409421568Z","durationInNanos":81514752,"serviceName":"database","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.net@peer@ip":"127.0.0.1","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8083,"span.attributes.http@status_text":"OK","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140307275923408","resource.attributes.service@name":"database","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"DELETE","span.attributes.http@user_agent":"python-requests/2.25.1","span.attributes.net@peer@port":55970,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@route":"/cart_sold","span.attributes.http@host":"localhost:8083","span.attributes.http@target":"/cart_sold","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":200}
{"index":{"_id":"303b76b989099bb5"}}
{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"303b76b989099bb5","traceState":"","parentSpanId":"e2ab54f8e8a03c99","name":"HTTP DELETE","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.325160960Z","endTime":"2021-03-25T17:23:59.430193920Z","durationInNanos":105032960,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.http@url":"http://localhost:8083/cart_sold","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.http@status_text":"OK","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.requests","span.attributes.http@method":"DELETE","resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@status_code":200}
-{"index":{"_id":"ba677184b5efee9c"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"ba677184b5efee9c","traceState":"","parentSpanId":"05d70136fe1f5159","name":"/logs","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:23:59.461002874Z","endTime":"2021-03-25T17:23:59.463725749Z","durationInNanos":2722875,"serviceName":"analytics-service","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.net@peer@ip":"127.0.0.1","span.attributes.http@url":"http://localhost:8087/logs","span.attributes.thread@name":"http-nio-8087-exec-8","instrumentationLibrary.version":"0.10.1","resource.attributes.telemetry@sdk@language":"java","span.attributes.thread@id":135,"resource.attributes.telemetry@sdk@version":"0.10.0","resource.attributes.service@name":"analytics-service","status.code":0,"instrumentationLibrary.name":"io.opentelemetry.auto.servlet","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.25.1","span.attributes.net@peer@port":56692,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@auto@version":"0.10.1","span.attributes.http@flavor":"HTTP/1.1","span.attributes.http@status_code":200,"span.attributes.http@client_ip":"127.0.0.1"}
-{"index":{"_id":"3ed514d3a35fcf2f"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"3ed514d3a35fcf2f","traceState":"","parentSpanId":"c8fff65b158a58b0","name":"cart_sold","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.328946176Z","endTime":"2021-03-25T17:23:59.396863488Z","durationInNanos":67917312,"serviceName":"database","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@sdk@language":"python","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140307275923408","resource.attributes.service@name":"database","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","status.code":0,"instrumentationLibrary.name":"__main__"}
-{"index":{"_id":"a1464485edf9588e"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"a1464485edf9588e","traceState":"","parentSpanId":"3ed514d3a35fcf2f","name":"mysql.APM","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.351120384Z","endTime":"2021-03-25T17:23:59.381280256Z","durationInNanos":30159872,"serviceName":"database","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.db@user":"root","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.net@peer@name":"localhost","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140307275923408","resource.attributes.service@name":"database","span.attributes.component":"mysql","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.mysql","span.attributes.db@type":"sql","span.attributes.net@peer@port":3306,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.db@instance":"APM","span.attributes.db@statement":"TRUNCATE TABLE User_Carts","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal"}
-{"index":{"_id":"05d70136fe1f5159"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"05d70136fe1f5159","traceState":"","parentSpanId":"e2ab54f8e8a03c99","name":"HTTP POST","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.447067904Z","endTime":"2021-03-25T17:23:59.466000896Z","durationInNanos":18932992,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.http@url":"http://localhost:8087/logs","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.http@status_text":"","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.requests","span.attributes.http@method":"POST","resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@status_code":200}
-{"index":{"_id":"e2ab54f8e8a03c99"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"e2ab54f8e8a03c99","traceState":"","parentSpanId":"f9d9427c810291d8","name":"pay_order","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.324906496Z","endTime":"2021-03-25T17:23:59.473705472Z","durationInNanos":148798976,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@sdk@language":"python","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","status.code":0,"instrumentationLibrary.name":"__main__"}
-{"index":{"_id":"7df5609a6d104736"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"7df5609a6d104736","traceState":"","parentSpanId":"542385797ac7122c","name":"HTTP POST","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.321473280Z","endTime":"2021-03-25T17:23:59.490911488Z","durationInNanos":169438208,"serviceName":"frontend-client","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.http@url":"http://localhost:8088/pay_order","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.http@status_text":"OK","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@name":"frontend-client","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.requests","span.attributes.http@method":"POST","resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@status_code":200}
-{"index":{"_id":"05ef9498724dc42f"}}
-{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"05ef9498724dc42f","traceState":"","parentSpanId":"ba677184b5efee9c","name":"LoggingController.save","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.461838595Z","endTime":"2021-03-25T17:23:59.463482824Z","durationInNanos":1644229,"serviceName":"analytics-service","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.thread@name":"http-nio-8087-exec-8","resource.attributes.telemetry@sdk@name":"opentelemetry","instrumentationLibrary.version":"0.10.1","resource.attributes.telemetry@sdk@language":"java","span.attributes.thread@id":135,"resource.attributes.telemetry@auto@version":"0.10.1","resource.attributes.telemetry@sdk@version":"0.10.0","resource.attributes.service@name":"analytics-service","status.code":0,"instrumentationLibrary.name":"io.opentelemetry.auto.spring-webmvc"}
-{"index":{"_id":"eea507e2c1767a48"}}
-{"traceId":"24112fdc5dfb6886638e64458220b1c8","spanId":"eea507e2c1767a48","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:42:17.381757696Z","endTime":"2021-03-25T17:42:17.383773440Z","durationInNanos":2015744,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:42:17.383773440Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":2015744,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":37610,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
-{"index":{"_id":"a32571a7f379563e"}}
-{"traceId":"f9389809a15b165300bf99ca10c1d094","spanId":"a32571a7f379563e","traceState":"","parentSpanId":"","name":"HTTP GET","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:42:42.526520320Z","endTime":"2021-03-25T17:42:42.527678720Z","durationInNanos":1158400,"serviceName":"recommendation","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP GET","traceGroupFields.endTime":"2021-03-25T17:42:42.527678720Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1158400,"span.attributes.net@peer@ip":"139.162.75.102","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8086,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140465266593744","resource.attributes.service@name":"recommendation","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"GET","span.attributes.http@user_agent":"HTTP Banner Detection (https://security.ipip.net)","span.attributes.net@peer@port":43096,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8086","span.attributes.http@target":"/","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
-{"index":{"_id":"fc11194d7d60a403"}}
-{"traceId":"5c8f22e7dce504a5b7610590d5426b16","spanId":"fc11194d7d60a403","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:25:41.732983296Z","endTime":"2021-03-25T17:25:41.734188544Z","durationInNanos":1205248,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:25:41.734188544Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1205248,"span.attributes.net@peer@ip":"128.199.87.139","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.12.4","span.attributes.net@peer@port":59096,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
-{"index":{"_id":"8f0e5fd10849cc70"}}
-{"traceId":"f151842ced0cd956ec005da199424336","spanId":"8f0e5fd10849cc70","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:48:05.517435904Z","endTime":"2021-03-25T17:48:05.518697728Z","durationInNanos":1261824,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:48:05.518697728Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1261824,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":59430,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
-{"index":{"_id":"244bc4ca978dd618"}}
-{"traceId":"be0a3dceda2ecf601fd2e476fef3ee07","spanId":"244bc4ca978dd618","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:55:12.854892800Z","endTime":"2021-03-25T17:55:12.856072192Z","durationInNanos":1179392,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:55:12.856072192Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1179392,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":35686,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
-{ "index":{"_id": "fe945197d943bda9"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "fe945197d943bda9", "traceState": "", "parentSpanId": "2bdbeb0df10ab869", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.022309888Z", "endTime": "2021-04-20T20:33:42.047018752Z", "durationInNanos": 24708864, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "2bdbeb0df10ab869"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "2bdbeb0df10ab869", "traceState": "", "parentSpanId": "7a5994c2d61252d8", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.002375424Z", "endTime": "2021-04-20T20:33:42.050758400Z", "durationInNanos": 48382976, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "bae5c2ac73588d38"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "bae5c2ac73588d38", "traceState": "", "parentSpanId": "d6668b8cd17b28aa", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.999037184Z", "endTime": "2021-04-20T20:33:42.070543360Z", "durationInNanos": 71506176, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "d6668b8cd17b28aa"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "d6668b8cd17b28aa", "traceState": "", "parentSpanId": "2786ea5cfba1d51c", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.998258944Z", "endTime": "2021-04-20T20:33:42.073518592Z", "durationInNanos": 75259648, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60962, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "de34ef4183a4705b"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "de34ef4183a4705b", "traceState": "", "parentSpanId": "1e0ea651a120db7b", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.502849536Z", "endTime": "2021-04-20T20:33:42.529717248Z", "durationInNanos": 26867712, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "cdf9197db50c18a4"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "cdf9197db50c18a4", "traceState": "", "parentSpanId": "baa1e8371ec989bd", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.543471872Z", "endTime": "2021-04-20T20:33:42.573529344Z", "durationInNanos": 30057472, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58602, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "baa1e8371ec989bd"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "baa1e8371ec989bd", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.541210624Z", "endTime": "2021-04-20T20:33:42.578594816Z", "durationInNanos": 37384192, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a545017537d582f9"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "a545017537d582f9", "traceState": "", "parentSpanId": "48ab22a6aa9ead3d", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.583665664Z", "endTime": "2021-04-20T20:33:42.615355392Z", "durationInNanos": 31689728, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58606, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "868f60191f3524c9"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "868f60191f3524c9", "traceState": "", "parentSpanId": "007459ff1ddd5dfb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.496294144Z", "endTime": "2021-04-20T20:33:42.638115584Z", "durationInNanos": 141821440, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "5e7bc4f9aae01a8f"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "5e7bc4f9aae01a8f", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.385450240Z", "endTime": "2021-04-20T20:33:43.469037824Z", "durationInNanos": 83587584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "5d8912365e6688f3"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "5d8912365e6688f3", "traceState": "", "parentSpanId": "e272f67b8738c361", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.826181376Z", "endTime": "2021-04-20T20:33:43.875000320Z", "durationInNanos": 48818944, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7e35eb6c56afcde0"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "7e35eb6c56afcde0", "traceState": "", "parentSpanId": "5b366e385260a8f1", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.822093312Z", "endTime": "2021-04-20T20:33:43.896168448Z", "durationInNanos": 74075136, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32772, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "5b366e385260a8f1"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "5b366e385260a8f1", "traceState": "", "parentSpanId": "c785f8a4fa3c337f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.819960576Z", "endTime": "2021-04-20T20:33:43.900840704Z", "durationInNanos": 80880128, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c785f8a4fa3c337f"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "c785f8a4fa3c337f", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.819711488Z", "endTime": "2021-04-20T20:33:43.903628288Z", "durationInNanos": 83916800, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "959d996c94b64416"}}
-{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "959d996c94b64416", "traceState": "", "parentSpanId": "4ed24722154a0621", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.000507533Z", "endTime": "2021-04-20T20:33:39.001814067Z", "durationInNanos": 1306534, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "b04dd1440b46ea4a"}}
-{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "b04dd1440b46ea4a", "traceState": "", "parentSpanId": "1fbcd1691508fa92", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.859492193Z", "endTime": "2021-04-20T20:33:40.860705473Z", "durationInNanos": 1213280, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "4ed24722154a0621"}}
-{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "4ed24722154a0621", "traceState": "", "parentSpanId": "62acd7c17a0ba6b5", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.000001917Z", "endTime": "2021-04-20T20:33:39.001944606Z", "durationInNanos": 1942689, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57758, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "6dcf6a50115bf9bf"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "6dcf6a50115bf9bf", "traceState": "", "parentSpanId": "7052b8e18f95d355", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.293001852Z", "endTime": "2021-04-20T20:33:40.294769849Z", "durationInNanos": 1767997, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57788, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "a981fd033e3a7491"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "a981fd033e3a7491", "traceState": "", "parentSpanId": "3d3423c981805776", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.248002296Z", "endTime": "2021-04-20T20:33:41.250091967Z", "durationInNanos": 2089671, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57808, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "c2bf96e64de1f749"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "c2bf96e64de1f749", "traceState": "", "parentSpanId": "82f2995c402620bf", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.064002408Z", "endTime": "2021-04-20T20:33:42.066510378Z", "durationInNanos": 2507970, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57830, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "7d14b353b41504e2"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "7d14b353b41504e2", "traceState": "", "parentSpanId": "66305d54c87ada37", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.888001836Z", "endTime": "2021-04-20T20:33:43.889846781Z", "durationInNanos": 1844945, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57872, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "638057deacc19370"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "638057deacc19370", "traceState": "", "parentSpanId": "570073e77e68be9d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.210460160Z", "endTime": "2021-04-20T20:33:44.211786496Z", "durationInNanos": 1326336, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "72fd9aa427e26550"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "72fd9aa427e26550", "traceState": "", "parentSpanId": "63b924688fd8e338", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.184596992Z", "endTime": "2021-04-20T20:33:44.221891840Z", "durationInNanos": 37294848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58638, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "74a72003d10b4891"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "74a72003d10b4891", "traceState": "", "parentSpanId": "9d74d751ce8f5632", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.298237184Z", "endTime": "2021-04-20T20:33:44.299052800Z", "durationInNanos": 815616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "9d74d751ce8f5632"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "9d74d751ce8f5632", "traceState": "", "parentSpanId": "2311bcf70d68331c", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.278095616Z", "endTime": "2021-04-20T20:33:44.309211392Z", "durationInNanos": 31115776, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "d45da7dee8c886ed"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "d45da7dee8c886ed", "traceState": "", "parentSpanId": "8fb23e8fa1ec36c4", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.578994944Z", "endTime": "2021-04-20T20:33:44.579650560Z", "durationInNanos": 655616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "10c91a64a809f0f9"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "10c91a64a809f0f9", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.552633344Z", "endTime": "2021-04-20T20:33:44.611744256Z", "durationInNanos": 59110912, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7359981596903c3f"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "7359981596903c3f", "traceState": "", "parentSpanId": "61aa3d8d2d402633", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.946950400Z", "endTime": "2021-04-20T20:33:44.993092352Z", "durationInNanos": 46141952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "61aa3d8d2d402633"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "61aa3d8d2d402633", "traceState": "", "parentSpanId": "0fcb489ad5418516", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.946038528Z", "endTime": "2021-04-20T20:33:44.996396288Z", "durationInNanos": 50357760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58668, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "6f35a199b046be10"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "6f35a199b046be10", "traceState": "", "parentSpanId": "83e66a83f1a293d1", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.283089152Z", "endTime": "2021-04-20T20:33:45.284170496Z", "durationInNanos": 1081344, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "5205b0912292faea"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "5205b0912292faea", "traceState": "", "parentSpanId": "61e11870abc59f27", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.262661120Z", "endTime": "2021-04-20T20:33:45.291168768Z", "durationInNanos": 28507648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58678, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "3cf94093fb7bea7c"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "3cf94093fb7bea7c", "traceState": "", "parentSpanId": "075721f8c8fe8187", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.260254208Z", "endTime": "2021-04-20T20:33:45.306146816Z", "durationInNanos": 45892608, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "075721f8c8fe8187"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "075721f8c8fe8187", "traceState": "", "parentSpanId": "6164378b120c9a33", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.259456Z", "endTime": "2021-04-20T20:33:45.308376320Z", "durationInNanos": 48920320, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32822, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "fe4076542b41d40b"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "fe4076542b41d40b", "traceState": "", "parentSpanId": "68d63100ba9ee351", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.613371648Z", "endTime": "2021-04-20T20:33:45.614105088Z", "durationInNanos": 733440, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "4cc7f89e7a456e50"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "4cc7f89e7a456e50", "traceState": "", "parentSpanId": "8cf5c6a43ee7642e", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.672583936Z", "endTime": "2021-04-20T20:33:45.701916160Z", "durationInNanos": 29332224, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58696, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "ded3687b9758bf59"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "ded3687b9758bf59", "traceState": "", "parentSpanId": "8ca1e3b61d66dac5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.582414080Z", "endTime": "2021-04-20T20:33:45.724472064Z", "durationInNanos": 142057984, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9a880188bcb44cda"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "9a880188bcb44cda", "traceState": "", "parentSpanId": "22b1d496a103d5d4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.193865472Z", "endTime": "2021-04-20T20:33:46.233754624Z", "durationInNanos": 39889152, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "211e3fa733083be7"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "211e3fa733083be7", "traceState": "", "parentSpanId": "6f7eafee7d68115c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.259891200Z", "endTime": "2021-04-20T20:33:46.260595456Z", "durationInNanos": 704256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "203faf4d95696dc4"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "203faf4d95696dc4", "traceState": "", "parentSpanId": "01e2845682343300", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.239240960Z", "endTime": "2021-04-20T20:33:46.270526720Z", "durationInNanos": 31285760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58726, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "30652f6f8b511470"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "30652f6f8b511470", "traceState": "", "parentSpanId": "6abbf17273b9d804", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.151000320Z", "endTime": "2021-04-20T20:33:46.280569856Z", "durationInNanos": 129569536, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48470, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "6abbf17273b9d804"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "6abbf17273b9d804", "traceState": "", "parentSpanId": "cadc045e30deb39c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.148769024Z", "endTime": "2021-04-20T20:33:46.285116928Z", "durationInNanos": 136347904, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "86582d579095a4b2"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "86582d579095a4b2", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.145158144Z", "endTime": "2021-04-20T20:33:46.297544448Z", "durationInNanos": 152386304, "serviceName": "frontend-client", "events": [ { "time": "2021-04-20T20:33:46.297516032Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "AssertionError", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "/app/client.py", line 179, in checkout assert checkoutAPIRequest.status_code == 200 AssertionError """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "status.message": "AssertionError: ", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "733fc257ce126bd9"}}
-{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "733fc257ce126bd9", "traceState": "", "parentSpanId": "e270a32c23bb3d64", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.530245888Z", "endTime": "2021-04-20T20:33:46.552403200Z", "durationInNanos": 22157312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "d3e652fe39797f07"}}
-{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "d3e652fe39797f07", "traceState": "", "parentSpanId": "e35c1a3d860c70aa", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.501878016Z", "endTime": "2021-04-20T20:33:46.563703296Z", "durationInNanos": 61825280, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "93a311e112248f38"}}
-{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "93a311e112248f38", "traceState": "", "parentSpanId": "7d9e1df2e1915cb1", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.498651904Z", "endTime": "2021-04-20T20:33:46.581459456Z", "durationInNanos": 82807552, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "13738600ae869fe9"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "13738600ae869fe9", "traceState": "", "parentSpanId": "7c37927033d44c5c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.905734912Z", "endTime": "2021-04-20T20:33:46.906381056Z", "durationInNanos": 646144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "7c37927033d44c5c"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "7c37927033d44c5c", "traceState": "", "parentSpanId": "704ecef0adc44ed2", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.885713920Z", "endTime": "2021-04-20T20:33:46.910141696Z", "durationInNanos": 24427776, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "4bac6e5bfd5892b4"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "4bac6e5bfd5892b4", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.921752064Z", "endTime": "2021-04-20T20:33:46.926354688Z", "durationInNanos": 4602624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "ceb7f50ca3f6e4d8"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "ceb7f50ca3f6e4d8", "traceState": "", "parentSpanId": "5f0f95a6e744be7f", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.191190528Z", "endTime": "2021-04-20T20:33:47.221020672Z", "durationInNanos": 29830144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58764, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "5f0f95a6e744be7f"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "5f0f95a6e744be7f", "traceState": "", "parentSpanId": "3e1ca23a1316a089", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.188976640Z", "endTime": "2021-04-20T20:33:47.225834496Z", "durationInNanos": 36857856, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "c321930cea7a01b8"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "c321930cea7a01b8", "traceState": "", "parentSpanId": "45b57a8187c98ac7", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.285538560Z", "endTime": "2021-04-20T20:33:47.310507008Z", "durationInNanos": 24968448, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:47.310474496Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "f707df9bafaf7974"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "f707df9bafaf7974", "traceState": "", "parentSpanId": "1d9787eae41fc84d", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.182018048Z", "endTime": "2021-04-20T20:33:47.339902976Z", "durationInNanos": 157884928, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "1d9787eae41fc84d"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "1d9787eae41fc84d", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.181764352Z", "endTime": "2021-04-20T20:33:47.342982400Z", "durationInNanos": 161218048, "serviceName": "frontend-client", "events": [ { "time": "2021-04-20T20:33:47.342953472Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "AssertionError", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "/app/client.py", line 179, in checkout assert checkoutAPIRequest.status_code == 200 AssertionError """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "status.message": "AssertionError: ", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ad97f94c920dd63a"}}
-{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "ad97f94c920dd63a", "traceState": "", "parentSpanId": "5b03c5aa49169de7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.481642240Z", "endTime": "2021-04-20T20:33:47.486791168Z", "durationInNanos": 5148928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "526236d61de39741"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "526236d61de39741", "traceState": "", "parentSpanId": "556b9dbb760a1f55", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.798135808Z", "endTime": "2021-04-20T20:33:47.798772480Z", "durationInNanos": 636672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "556b9dbb760a1f55"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "556b9dbb760a1f55", "traceState": "", "parentSpanId": "a0333ab0c0fb425e", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.778251008Z", "endTime": "2021-04-20T20:33:47.802673152Z", "durationInNanos": 24422144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "48c5f132edd1dce1"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "48c5f132edd1dce1", "traceState": "", "parentSpanId": "8d13c5fb5cb910ab", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.773860864Z", "endTime": "2021-04-20T20:33:47.903245568Z", "durationInNanos": 129384704, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32932, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f4fb15e340c39da3"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "f4fb15e340c39da3", "traceState": "", "parentSpanId": "36362df397ac500d", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.095176192Z", "endTime": "2021-04-20T20:33:48.123719936Z", "durationInNanos": 28543744, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58806, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9a8427df12be8522"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "9a8427df12be8522", "traceState": "", "parentSpanId": "60b801fae48abf9b", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.091967488Z", "endTime": "2021-04-20T20:33:48.140747776Z", "durationInNanos": 48780288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32950, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a23201e2aa2bf778"}}
-{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "a23201e2aa2bf778", "traceState": "", "parentSpanId": "e2ce196e32791fa8", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.390765568Z", "endTime": "2021-04-20T20:33:48.446376192Z", "durationInNanos": 55610624, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58816, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e2ce196e32791fa8"}}
-{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "e2ce196e32791fa8", "traceState": "", "parentSpanId": "33de151285a224b8", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.388591104Z", "endTime": "2021-04-20T20:33:48.451160064Z", "durationInNanos": 62568960, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "5d15d016d2efc520"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "5d15d016d2efc520", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.724736768Z", "endTime": "2021-04-20T20:33:48.783604992Z", "durationInNanos": 58868224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1ceb1ee0c0c5a3d7"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "1ceb1ee0c0c5a3d7", "traceState": "", "parentSpanId": "81de5d2c6aa0859e", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.042982400Z", "endTime": "2021-04-20T20:33:49.067498752Z", "durationInNanos": 24516352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "8397412a4368c536"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "8397412a4368c536", "traceState": "", "parentSpanId": "b3e2c3a351f4d833", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.322510254Z", "endTime": "2021-04-20T20:33:44.323607252Z", "durationInNanos": 1096998, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "1b7829585cbc0b01"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "1b7829585cbc0b01", "traceState": "", "parentSpanId": "552e8512fb52ccb5", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.596480225Z", "endTime": "2021-04-20T20:33:44.597655556Z", "durationInNanos": 1175331, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "5610211164d655f6"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "5610211164d655f6", "traceState": "", "parentSpanId": "d2025fa5bde68d4c", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.006493344Z", "endTime": "2021-04-20T20:33:45.007802848Z", "durationInNanos": 1309504, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "e8af87596517f6bf"}}
-{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "e8af87596517f6bf", "traceState": "", "parentSpanId": "934a3522bd05ed13", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.484509396Z", "endTime": "2021-04-20T20:33:47.485676993Z", "durationInNanos": 1167597, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "d2025fa5bde68d4c"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "d2025fa5bde68d4c", "traceState": "", "parentSpanId": "5ce9b5237f2b2bbd", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.006001630Z", "endTime": "2021-04-20T20:33:45.007923360Z", "durationInNanos": 1921730, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57912, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "fec494ea1cd015e3"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "fec494ea1cd015e3", "traceState": "", "parentSpanId": "04f07ddda2ec832d", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.301002074Z", "endTime": "2021-04-20T20:33:45.302720699Z", "durationInNanos": 1718625, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57922, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "2ac8b4cda3c0f1f9"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "2ac8b4cda3c0f1f9", "traceState": "", "parentSpanId": "d7ae88514a0b9617", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.711001942Z", "endTime": "2021-04-20T20:33:45.712721718Z", "durationInNanos": 1719776, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57940, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "e4f2d38e4f128be7"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "e4f2d38e4f128be7", "traceState": "", "parentSpanId": "4bac6e5bfd5892b4", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.924001969Z", "endTime": "2021-04-20T20:33:46.925747176Z", "durationInNanos": 1745207, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57996, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "74dbc2be658b50d8"}}
-{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "74dbc2be658b50d8", "traceState": "", "parentSpanId": "d3bce0f9acda8b4e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.456001869Z", "endTime": "2021-04-20T20:33:48.457554150Z", "durationInNanos": 1552281, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58060, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "0c1e1c234af592e4"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "0c1e1c234af592e4", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.039726592Z", "endTime": "2021-04-20T20:33:49.077204224Z", "durationInNanos": 37477632, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c6c238ba3d8255f4"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "c6c238ba3d8255f4", "traceState": "", "parentSpanId": "27d4fe07134ea308", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.000050176Z", "endTime": "2021-04-20T20:33:49.130614784Z", "durationInNanos": 130564608, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "fb628320c3bd92c1"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "fb628320c3bd92c1", "traceState": "", "parentSpanId": "c7c175f4366ce130", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.312768512Z", "endTime": "2021-04-20T20:33:49.313572864Z", "durationInNanos": 804352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "d03fde256c0d5e87"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "d03fde256c0d5e87", "traceState": "", "parentSpanId": "1e3aecf00776002e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.354710528Z", "endTime": "2021-04-20T20:33:49.359258880Z", "durationInNanos": 4548352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "8979ca2f03690516"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "8979ca2f03690516", "traceState": "", "parentSpanId": "f79bee55c88da9dd", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.282687488Z", "endTime": "2021-04-20T20:33:49.369189632Z", "durationInNanos": 86502144, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b5e9c2df83b5c950"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "b5e9c2df83b5c950", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.604470016Z", "endTime": "2021-04-20T20:33:49.642110208Z", "durationInNanos": 37640192, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId apple", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "4167f155e728b1bf"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "4167f155e728b1bf", "traceState": "", "parentSpanId": "bb41f245f32492e4", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.519380224Z", "endTime": "2021-04-20T20:33:49.656816384Z", "durationInNanos": 137436160, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60116, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "5175f8f67d791920"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "5175f8f67d791920", "traceState": "", "parentSpanId": "cc39a5b2d98e4127", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.871913728Z", "endTime": "2021-04-20T20:33:49.873131008Z", "durationInNanos": 1217280, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "ecc02e73350ce790"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "ecc02e73350ce790", "traceState": "", "parentSpanId": "de9f1128bf12b7b9", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.848557312Z", "endTime": "2021-04-20T20:33:49.907510272Z", "durationInNanos": 58952960, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "1861602b0fed74c0"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "1861602b0fed74c0", "traceState": "", "parentSpanId": "a9019c51b85c9ac6", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.847567872Z", "endTime": "2021-04-20T20:33:49.920374784Z", "durationInNanos": 72806912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33026, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a9019c51b85c9ac6"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "a9019c51b85c9ac6", "traceState": "", "parentSpanId": "034ed8cfb8ba682a", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.845530624Z", "endTime": "2021-04-20T20:33:49.925377792Z", "durationInNanos": 79847168, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d6737261234573e3"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "d6737261234573e3", "traceState": "", "parentSpanId": "0fa03fca5ea8c051", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.143993600Z", "endTime": "2021-04-20T20:33:50.172754688Z", "durationInNanos": 28761088, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58892, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e684414d71481506"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "e684414d71481506", "traceState": "", "parentSpanId": "55b6879fed1f14b7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.242910208Z", "endTime": "2021-04-20T20:33:50.243621632Z", "durationInNanos": 711424, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "25d2d59e3e627ee7"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "25d2d59e3e627ee7", "traceState": "", "parentSpanId": "6a539e36635daed1", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.481526016Z", "endTime": "2021-04-20T20:33:50.506380544Z", "durationInNanos": 24854528, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "13bed71d66dcc038"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "13bed71d66dcc038", "traceState": "", "parentSpanId": "9232ae83ea33fee8", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.478371840Z", "endTime": "2021-04-20T20:33:50.514467584Z", "durationInNanos": 36095744, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c29268a1fd31d7d1"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "c29268a1fd31d7d1", "traceState": "", "parentSpanId": "9232ae83ea33fee8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.517328128Z", "endTime": "2021-04-20T20:33:50.522111488Z", "durationInNanos": 4783360, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7ca71ea50061e17a"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "7ca71ea50061e17a", "traceState": "", "parentSpanId": "2e36371a9ffe2dc0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.751403008Z", "endTime": "2021-04-20T20:33:50.752038912Z", "durationInNanos": 635904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "c7c7d4012d81b142"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "c7c7d4012d81b142", "traceState": "", "parentSpanId": "e7287e116f07049d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.792653056Z", "endTime": "2021-04-20T20:33:50.793349632Z", "durationInNanos": 696576, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "ecc0e3f8be5250dd"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "ecc0e3f8be5250dd", "traceState": "", "parentSpanId": "cebaa948cfa4cc19", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.811156480Z", "endTime": "2021-04-20T20:33:50.840189440Z", "durationInNanos": 29032960, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58930, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "534023ef492ea75d"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "534023ef492ea75d", "traceState": "", "parentSpanId": "c5ab512bce3105ef", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.158956032Z", "endTime": "2021-04-20T20:33:51.159533568Z", "durationInNanos": 577536, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "e9893407bba95bf0"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "e9893407bba95bf0", "traceState": "", "parentSpanId": "76dfb45c3ba7873f", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.136340992Z", "endTime": "2021-04-20T20:33:51.171475200Z", "durationInNanos": 35134208, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "608bd5e547e88e3e"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "608bd5e547e88e3e", "traceState": "", "parentSpanId": "2b7af871bd8cd43f", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.475266048Z", "endTime": "2021-04-20T20:33:51.480210688Z", "durationInNanos": 4944640, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "bd638d2bf13e4f41"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "bd638d2bf13e4f41", "traceState": "", "parentSpanId": "8defb053817ab655", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.412930816Z", "endTime": "2021-04-20T20:33:51.485616640Z", "durationInNanos": 72685824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33094, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "dcab66f931f7fc5b"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "dcab66f931f7fc5b", "traceState": "", "parentSpanId": "", "name": "client_pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.410483968Z", "endTime": "2021-04-20T20:33:51.493332480Z", "durationInNanos": 82848512, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_pay_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "9b81a0201a53b84c"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "9b81a0201a53b84c", "traceState": "", "parentSpanId": "de85f1e0d746da28", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.682416128Z", "endTime": "2021-04-20T20:33:51.712218624Z", "durationInNanos": 29802496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58960, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e2a28bb8e6bf64ca"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "e2a28bb8e6bf64ca", "traceState": "", "parentSpanId": "3301dd384d83dc66", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.680000512Z", "endTime": "2021-04-20T20:33:51.727677440Z", "durationInNanos": 47676928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "9de35fba7cb7c4a3"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "9de35fba7cb7c4a3", "traceState": "", "parentSpanId": "637cedb12aa88454", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.677016320Z", "endTime": "2021-04-20T20:33:51.734535680Z", "durationInNanos": 57519360, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "637cedb12aa88454"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "637cedb12aa88454", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.676719872Z", "endTime": "2021-04-20T20:33:51.737385984Z", "durationInNanos": 60666112, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "06f27e83cdad4af6"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "06f27e83cdad4af6", "traceState": "", "parentSpanId": "439eff3f753e8e67", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.995934208Z", "endTime": "2021-04-20T20:33:52.024369152Z", "durationInNanos": 28434944, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58974, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "1fdfb0d6a0c76960"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "1fdfb0d6a0c76960", "traceState": "", "parentSpanId": "a748c29eeb1d7e59", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.231162624Z", "endTime": "2021-04-20T20:33:52.231785216Z", "durationInNanos": 622592, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "18172e3a91f55d39"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "18172e3a91f55d39", "traceState": "", "parentSpanId": "a748c29eeb1d7e59", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.235772416Z", "endTime": "2021-04-20T20:33:52.256177152Z", "durationInNanos": 20404736, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "a748c29eeb1d7e59"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "a748c29eeb1d7e59", "traceState": "", "parentSpanId": "adbedfaf38a87985", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.211242240Z", "endTime": "2021-04-20T20:33:52.259230720Z", "durationInNanos": 47988480, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "adbedfaf38a87985"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "adbedfaf38a87985", "traceState": "", "parentSpanId": "ba003d4618b074f7", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.210340352Z", "endTime": "2021-04-20T20:33:52.262700032Z", "durationInNanos": 52359680, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58988, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "66dd3959b912162c"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "66dd3959b912162c", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.204713472Z", "endTime": "2021-04-20T20:33:52.288004096Z", "durationInNanos": 83290624, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "4543b1bfbb5964c3"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "4543b1bfbb5964c3", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.497326080Z", "endTime": "2021-04-20T20:33:52.532990720Z", "durationInNanos": 35664640, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "45c65220620defaf"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "45c65220620defaf", "traceState": "", "parentSpanId": "b4e1a6127d470651", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.539106304Z", "endTime": "2021-04-20T20:33:52.563575552Z", "durationInNanos": 24469248, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "179c014a060ab428"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "179c014a060ab428", "traceState": "", "parentSpanId": "f6691ab391b0e350", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.598380800Z", "endTime": "2021-04-20T20:33:52.599080704Z", "durationInNanos": 699904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "f6691ab391b0e350"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "f6691ab391b0e350", "traceState": "", "parentSpanId": "f3dc908cffab10fe", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.578200832Z", "endTime": "2021-04-20T20:33:52.603235328Z", "durationInNanos": 25034496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "6a8149f2f3269df9"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "6a8149f2f3269df9", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.614755328Z", "endTime": "2021-04-20T20:33:52.619177472Z", "durationInNanos": 4422144, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c52d1f54270c1a88"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "c52d1f54270c1a88", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.493635840Z", "endTime": "2021-04-20T20:33:52.632568064Z", "durationInNanos": 138932224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "5b1ed6116a19ebcc"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "5b1ed6116a19ebcc", "traceState": "", "parentSpanId": "14148032cdebd6e5", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.698918400Z", "endTime": "2021-04-20T20:33:52.699564800Z", "durationInNanos": 646400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "680639d2b7681a2a"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "680639d2b7681a2a", "traceState": "", "parentSpanId": "d85ef60c6b05ea1e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.675642368Z", "endTime": "2021-04-20T20:33:52.711814144Z", "durationInNanos": 36171776, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f30e9c92926901d9"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "f30e9c92926901d9", "traceState": "", "parentSpanId": "70e7adcb0023b919", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.756263936Z", "endTime": "2021-04-20T20:33:52.785140224Z", "durationInNanos": 28876288, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59024, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "1aa4ab0af82bbbb2"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "1aa4ab0af82bbbb2", "traceState": "", "parentSpanId": "b6b76ad0ea7a18e0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.954985472Z", "endTime": "2021-04-20T20:33:52.978256896Z", "durationInNanos": 23271424, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "b6b76ad0ea7a18e0"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "b6b76ad0ea7a18e0", "traceState": "", "parentSpanId": "bffbe84728e92b6d", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.930167040Z", "endTime": "2021-04-20T20:33:52.981641472Z", "durationInNanos": 51474432, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "68f6536a0523f7f3"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "68f6536a0523f7f3", "traceState": "", "parentSpanId": "2badcc8448bd5c5b", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.215277568Z", "endTime": "2021-04-20T20:33:53.253143808Z", "durationInNanos": 37866240, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "a4030e9ad85b2a92"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "a4030e9ad85b2a92", "traceState": "", "parentSpanId": "057ca06095200357", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.259318272Z", "endTime": "2021-04-20T20:33:53.284444928Z", "durationInNanos": 25126656, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:53.284412416Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "4244f688b5a95a26"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "4244f688b5a95a26", "traceState": "", "parentSpanId": "49bd0e3a571e477d", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.301197056Z", "endTime": "2021-04-20T20:33:53.326327296Z", "durationInNanos": 25130240, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:53.326294016Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "49bd0e3a571e477d"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "49bd0e3a571e477d", "traceState": "", "parentSpanId": "06d1242a51405187", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.300201216Z", "endTime": "2021-04-20T20:33:53.330773248Z", "durationInNanos": 30572032, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId apple", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59056, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "a03d0ff09010abc3"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "a03d0ff09010abc3", "traceState": "", "parentSpanId": "66a2144a58008463", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.211857408Z", "endTime": "2021-04-20T20:33:53.345646848Z", "durationInNanos": 133789440, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "1baf1e42d2eaae2a"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "1baf1e42d2eaae2a", "traceState": "", "parentSpanId": "cefea796ccf54813", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.429764096Z", "endTime": "2021-04-20T20:33:53.493248256Z", "durationInNanos": 63484160, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "1dc7b46c2357c388"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "1dc7b46c2357c388", "traceState": "", "parentSpanId": "2aec9c6345d7c6b3", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.426487808Z", "endTime": "2021-04-20T20:33:53.509910016Z", "durationInNanos": 83422208, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "86b490f5558fa709"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "86b490f5558fa709", "traceState": "", "parentSpanId": "32c7b65db72d6298", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.125418594Z", "endTime": "2021-04-20T20:33:49.126411716Z", "durationInNanos": 993122, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "f8d135e17dd59043"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "f8d135e17dd59043", "traceState": "", "parentSpanId": "1fe046d4f9f3bd13", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.722447259Z", "endTime": "2021-04-20T20:33:51.723605629Z", "durationInNanos": 1158370, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "32c7b65db72d6298"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "32c7b65db72d6298", "traceState": "", "parentSpanId": "d74d48bf3431c487", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.125001550Z", "endTime": "2021-04-20T20:33:49.126513995Z", "durationInNanos": 1512445, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58088, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "50347b6be84490e4"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "50347b6be84490e4", "traceState": "", "parentSpanId": "d03fde256c0d5e87", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.356001691Z", "endTime": "2021-04-20T20:33:49.357803832Z", "durationInNanos": 1802141, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58098, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "d0c7228a8eb81715"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "d0c7228a8eb81715", "traceState": "", "parentSpanId": "268c00835c4cc7ac", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.850001822Z", "endTime": "2021-04-20T20:33:50.851659846Z", "durationInNanos": 1658024, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58174, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "0f929cd09feb717a"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "0f929cd09feb717a", "traceState": "", "parentSpanId": "84584d9e50950ea5", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.818001824Z", "endTime": "2021-04-20T20:33:52.819591628Z", "durationInNanos": 1589804, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58268, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "b272143e732a91e9"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "b272143e732a91e9", "traceState": "", "parentSpanId": "477408f3368f28af", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.995002208Z", "endTime": "2021-04-20T20:33:52.996554316Z", "durationInNanos": 1552108, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58278, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "06e4387a53eec8ae"}}
-{ "traceId": "4626b16656c8131c17bef721f94f39d0", "spanId": "06e4387a53eec8ae", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:19.541728768Z", "endTime": "2021-04-20T20:33:19.544739584Z", "durationInNanos": 3010816, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8086, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 42362, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8086", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
-{ "index":{"_id": "60393741cd2ba5da"}}
-{ "traceId": "5a551c574ba60b0fddee0a98150ad7c6", "spanId": "60393741cd2ba5da", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:20.558674688Z", "endTime": "2021-04-20T20:33:20.561958656Z", "durationInNanos": 3283968, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8085, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 37624, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8085", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
-{ "index":{"_id": "840eaf798fcd7d6a"}}
-{ "traceId": "513e4f752e4411aa6d4b6b35878172f3", "spanId": "840eaf798fcd7d6a", "traceState": "", "parentSpanId": "d3c888f442bdf005", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:29.225169408Z", "endTime": "2021-04-20T20:33:29.237534464Z", "durationInNanos": 12365056, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59546, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
-{ "index":{"_id": "647e42f1b60baba6"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "647e42f1b60baba6", "traceState": "", "parentSpanId": "8e7e103a2e3a040f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:32.582873344Z", "endTime": "2021-04-20T20:33:32.583549440Z", "durationInNanos": 676096, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM Inventory_Items", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "519baeb3e108614d"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "519baeb3e108614d", "traceState": "", "parentSpanId": "65bcaf9c16235fec", "name": "getIntentory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.557999360Z", "endTime": "2021-04-20T20:33:32.590999808Z", "durationInNanos": 33000448, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58316, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_inventory", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "caed30931d6c8826"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "caed30931d6c8826", "traceState": "", "parentSpanId": "88484a1ee3c170cd", "name": "recommend", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.547260416Z", "endTime": "2021-04-20T20:33:32.628968960Z", "durationInNanos": 81708544, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8086, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 42416, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/recommend", "span.attributes.http@host": "localhost:8086", "span.attributes.http@target": "/recommend", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "40c037eaae087000"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "40c037eaae087000", "traceState": "", "parentSpanId": "55d7f80c6aff4ec7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.314483968Z", "endTime": "2021-04-20T20:33:34.349315328Z", "durationInNanos": 34831360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58344, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "ec44bfc9b38f6faf"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "ec44bfc9b38f6faf", "traceState": "", "parentSpanId": "ab460c6800da22bf", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.727146240Z", "endTime": "2021-04-20T20:33:34.727824384Z", "durationInNanos": 678144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "ab460c6800da22bf"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "ab460c6800da22bf", "traceState": "", "parentSpanId": "066eee06004804d5", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.707429632Z", "endTime": "2021-04-20T20:33:34.731620608Z", "durationInNanos": 24190976, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "066eee06004804d5"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "066eee06004804d5", "traceState": "", "parentSpanId": "bb8e3a8935263a0e", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.706544640Z", "endTime": "2021-04-20T20:33:34.734942208Z", "durationInNanos": 28397568, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58354, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "bb8e3a8935263a0e"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "bb8e3a8935263a0e", "traceState": "", "parentSpanId": "60845ba7d8c2aaf0", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.704376320Z", "endTime": "2021-04-20T20:33:34.739784704Z", "durationInNanos": 35408384, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "99d7b8673d19932d"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "99d7b8673d19932d", "traceState": "", "parentSpanId": "60845ba7d8c2aaf0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.742878464Z", "endTime": "2021-04-20T20:33:34.748727296Z", "durationInNanos": 5848832, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "174b6e4f69dd2d18"}}
-{ "traceId": "9cc5c0acce9b9acc05b1c8d082709609", "spanId": "174b6e4f69dd2d18", "traceState": "", "parentSpanId": "9b3c0b3ed5c876e6", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.171959296Z", "endTime": "2021-04-20T20:33:35.219812352Z", "durationInNanos": 47853056, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "6f9eca809cfd10f4"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "6f9eca809cfd10f4", "traceState": "", "parentSpanId": "1cfde34b0e64708d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.738551040Z", "endTime": "2021-04-20T20:33:35.739376640Z", "durationInNanos": 825600, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "cc1bd6dba046b476"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "cc1bd6dba046b476", "traceState": "", "parentSpanId": "bb9e8ac613f9c314", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.783496704Z", "endTime": "2021-04-20T20:33:35.784163328Z", "durationInNanos": 666624, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "17573d14a639e1d1"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "17573d14a639e1d1", "traceState": "", "parentSpanId": "285b2f9d476d9a6f", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:35.663353600Z", "endTime": "2021-04-20T20:33:35.810676480Z", "durationInNanos": 147322880, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60752, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c2340bad2c8d7620"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "c2340bad2c8d7620", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.660813824Z", "endTime": "2021-04-20T20:33:35.818663168Z", "durationInNanos": 157849344, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7fe759e9e512c8ff"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "7fe759e9e512c8ff", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.099666432Z", "endTime": "2021-04-20T20:33:36.100590592Z", "durationInNanos": 924160, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "3c71472fb76ad5e6"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "3c71472fb76ad5e6", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.107451904Z", "endTime": "2021-04-20T20:33:36.108079616Z", "durationInNanos": 627712, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "8e2e0e3da163fc3b"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "8e2e0e3da163fc3b", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.113731328Z", "endTime": "2021-04-20T20:33:36.139224064Z", "durationInNanos": 25492736, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "42b721754a8f6168"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "42b721754a8f6168", "traceState": "", "parentSpanId": "cb2b82acca479730", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.074103296Z", "endTime": "2021-04-20T20:33:36.142439680Z", "durationInNanos": 68336384, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ad7845eabc7145cd"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "ad7845eabc7145cd", "traceState": "", "parentSpanId": "db173bc10299861f", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.155145984Z", "endTime": "2021-04-20T20:33:36.160770816Z", "durationInNanos": 5624832, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "ac0d61f7be00cc09"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "ac0d61f7be00cc09", "traceState": "", "parentSpanId": "4f70367bf3c97d0e", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.574601472Z", "endTime": "2021-04-20T20:33:36.606697728Z", "durationInNanos": 32096256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58414, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "4f70367bf3c97d0e"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "4f70367bf3c97d0e", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.572322816Z", "endTime": "2021-04-20T20:33:36.611627264Z", "durationInNanos": 39304448, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "375cb3ef27c46997"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "375cb3ef27c46997", "traceState": "", "parentSpanId": "b5ef9ef1ecddda5e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.485675264Z", "endTime": "2021-04-20T20:33:36.629994496Z", "durationInNanos": 144319232, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "60019ca1c2f5ab8e"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "60019ca1c2f5ab8e", "traceState": "", "parentSpanId": "d3911d8b057539bb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.481851648Z", "endTime": "2021-04-20T20:33:36.647876864Z", "durationInNanos": 166025216, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a7fcdbe2bf6d6d75"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "a7fcdbe2bf6d6d75", "traceState": "", "parentSpanId": "7c058c08a86fc5a8", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.996497920Z", "endTime": "2021-04-20T20:33:37.070610176Z", "durationInNanos": 74112256, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7c058c08a86fc5a8"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "7c058c08a86fc5a8", "traceState": "", "parentSpanId": "68cf95323b3af152", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.995693312Z", "endTime": "2021-04-20T20:33:37.072949248Z", "durationInNanos": 77255936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60802, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "68cf95323b3af152"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "68cf95323b3af152", "traceState": "", "parentSpanId": "bfcda24f22004149", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.993572608Z", "endTime": "2021-04-20T20:33:37.077576704Z", "durationInNanos": 84004096, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "bfcda24f22004149"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "bfcda24f22004149", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.993322752Z", "endTime": "2021-04-20T20:33:37.080295680Z", "durationInNanos": 86972928, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "8fd6fd77a11f4983"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "8fd6fd77a11f4983", "traceState": "", "parentSpanId": "b4f529ee6fed4e49", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:37.408389376Z", "endTime": "2021-04-20T20:33:37.443986176Z", "durationInNanos": 35596800, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58436, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "71529953e9aa20e1"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "71529953e9aa20e1", "traceState": "", "parentSpanId": "67a615bb3d2aef86", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.544745216Z", "endTime": "2021-04-20T20:33:37.549624064Z", "durationInNanos": 4878848, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "523a0808d6e0be58"}}
-{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "523a0808d6e0be58", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.780772864Z", "endTime": "2021-04-20T20:33:37.882267392Z", "durationInNanos": 101494528, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "aaa95e9f50a4baa3"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "aaa95e9f50a4baa3", "traceState": "", "parentSpanId": "7bc2fe0a60e01dba", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.200260352Z", "endTime": "2021-04-20T20:33:38.226785024Z", "durationInNanos": 26524672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "56925faca063f848"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "56925faca063f848", "traceState": "", "parentSpanId": "1b26c8058d3cd7b6", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.240576512Z", "endTime": "2021-04-20T20:33:38.272510720Z", "durationInNanos": 31934208, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58474, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "36883585e85d1b73"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "36883585e85d1b73", "traceState": "", "parentSpanId": "0f425b86cb459271", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.619970304Z", "endTime": "2021-04-20T20:33:38.653283072Z", "durationInNanos": 33312768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58498, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e8365c37ca6c41a9"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "e8365c37ca6c41a9", "traceState": "", "parentSpanId": "95441fc1d382e48d", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.702615040Z", "endTime": "2021-04-20T20:33:38.707414784Z", "durationInNanos": 4799744, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "cc87be09db83951c"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "cc87be09db83951c", "traceState": "", "parentSpanId": "eb63409f597c3607", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.557328128Z", "endTime": "2021-04-20T20:33:38.718940928Z", "durationInNanos": 161612800, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "eb63409f597c3607"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "eb63409f597c3607", "traceState": "", "parentSpanId": "07b4d48cb660e9cc", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.556882688Z", "endTime": "2021-04-20T20:33:38.734543616Z", "durationInNanos": 177660928, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "d250018f35242056"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "d250018f35242056", "traceState": "", "parentSpanId": "c9b6a51576561f98", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.065582317Z", "endTime": "2021-04-20T20:33:37.066913Z", "durationInNanos": 1330683, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "7b78d2bea411b2fe"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "7b78d2bea411b2fe", "traceState": "", "parentSpanId": "0a9ab07c9f5e7d29", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.359002058Z", "endTime": "2021-04-20T20:33:34.361727904Z", "durationInNanos": 2725846, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57588, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "7145d5e8e15acfb7"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "7145d5e8e15acfb7", "traceState": "", "parentSpanId": "99d7b8673d19932d", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.745001766Z", "endTime": "2021-04-20T20:33:34.747694532Z", "durationInNanos": 2692766, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57598, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "474039eb574aec04"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "474039eb574aec04", "traceState": "", "parentSpanId": "ad7845eabc7145cd", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.157001583Z", "endTime": "2021-04-20T20:33:36.159234806Z", "durationInNanos": 2233223, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57638, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "77243c434c2fcb1f"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "77243c434c2fcb1f", "traceState": "", "parentSpanId": "937fb8345b252adb", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.617002014Z", "endTime": "2021-04-20T20:33:36.619561838Z", "durationInNanos": 2559824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57658, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "fd955727cb8de558"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "fd955727cb8de558", "traceState": "", "parentSpanId": "f211085459dee231", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.284002091Z", "endTime": "2021-04-20T20:33:38.286466012Z", "durationInNanos": 2463921, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57720, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "c1e60aa906af446c"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "c1e60aa906af446c", "traceState": "", "parentSpanId": "c5280d05b1704e38", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.302001808Z", "endTime": "2021-04-20T20:33:38.303866754Z", "durationInNanos": 1864946, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57722, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "f251b6b23136a553"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "f251b6b23136a553", "traceState": "", "parentSpanId": "76ac0909a315d25c", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.726001732Z", "endTime": "2021-04-20T20:33:38.728225906Z", "durationInNanos": 2224174, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57748, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "3746bae316ced457"}}
-{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "3746bae316ced457", "traceState": "", "parentSpanId": "8eafdbb08ef33fac", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:39.773298688Z", "endTime": "2021-04-20T20:33:39.775022848Z", "durationInNanos": 1724160, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "0afb5a2b1848c74b"}}
-{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "0afb5a2b1848c74b", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.747136Z", "endTime": "2021-04-20T20:33:39.807513856Z", "durationInNanos": 60377856, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "669d2b7892e6854c"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "669d2b7892e6854c", "traceState": "", "parentSpanId": "9253cd2f27e55a6f", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.228339200Z", "endTime": "2021-04-20T20:33:40.299048192Z", "durationInNanos": 70708992, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "59443367c68e77d9"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "59443367c68e77d9", "traceState": "", "parentSpanId": "c3bb9b0cacfb19ea", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.185568512Z", "endTime": "2021-04-20T20:33:41.234750208Z", "durationInNanos": 49181696, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "3d3423c981805776"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "3d3423c981805776", "traceState": "", "parentSpanId": "a4ba523cda11d1d3", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.246229760Z", "endTime": "2021-04-20T20:33:41.251002880Z", "durationInNanos": 4773120, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e3496923e8587b46"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "e3496923e8587b46", "traceState": "", "parentSpanId": "6b60bf20aca25776", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.625234688Z", "endTime": "2021-04-20T20:33:41.654554624Z", "durationInNanos": 29319936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58576, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "18af310c32c71ea5"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "18af310c32c71ea5", "traceState": "", "parentSpanId": "915cceedf89bd5f3", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.619891200Z", "endTime": "2021-04-20T20:33:41.677285120Z", "durationInNanos": 57393920, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7a5994c2d61252d8"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "7a5994c2d61252d8", "traceState": "", "parentSpanId": "903ebe485e8ce58d", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.001465600Z", "endTime": "2021-04-20T20:33:42.054217216Z", "durationInNanos": 52751616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58586, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "2786ea5cfba1d51c"}}
-{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "2786ea5cfba1d51c", "traceState": "", "parentSpanId": "e8aeb63bfa118068", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.996101888Z", "endTime": "2021-04-20T20:33:42.080325120Z", "durationInNanos": 84223232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/pay_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "694e40f773666591"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "694e40f773666591", "traceState": "", "parentSpanId": "de34ef4183a4705b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.522945280Z", "endTime": "2021-04-20T20:33:42.523687680Z", "durationInNanos": 742400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "7cd34262856a4d72"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "7cd34262856a4d72", "traceState": "", "parentSpanId": "d2b2b41a16075705", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.604768512Z", "endTime": "2021-04-20T20:33:42.605615360Z", "durationInNanos": 846848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "5bd2b2161742dcd5"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "5bd2b2161742dcd5", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.623602688Z", "endTime": "2021-04-20T20:33:42.628299008Z", "durationInNanos": 4696320, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "4eaffcf10b0ddc1b"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "4eaffcf10b0ddc1b", "traceState": "", "parentSpanId": "5204fe33a94fc5e5", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.495094784Z", "endTime": "2021-04-20T20:33:42.651653888Z", "durationInNanos": 156559104, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59848, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9645c99068238c29"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "9645c99068238c29", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.492572416Z", "endTime": "2021-04-20T20:33:42.660122112Z", "durationInNanos": 167549696, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "080f360f30d5f04d"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "080f360f30d5f04d", "traceState": "", "parentSpanId": "01b11afabc7fdc7f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.411759104Z", "endTime": "2021-04-20T20:33:43.413591296Z", "durationInNanos": 1832192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "01b11afabc7fdc7f"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "01b11afabc7fdc7f", "traceState": "", "parentSpanId": "54419fc75e901eee", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.391958528Z", "endTime": "2021-04-20T20:33:43.440197888Z", "durationInNanos": 48239360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "54419fc75e901eee"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "54419fc75e901eee", "traceState": "", "parentSpanId": "85fb245e31172689", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.391038976Z", "endTime": "2021-04-20T20:33:43.443544064Z", "durationInNanos": 52505088, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58618, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "85fb245e31172689"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "85fb245e31172689", "traceState": "", "parentSpanId": "a0bed7d434593b60", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.388828416Z", "endTime": "2021-04-20T20:33:43.448487936Z", "durationInNanos": 59659520, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "36695d818f9b4e9a"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "36695d818f9b4e9a", "traceState": "", "parentSpanId": "5268497625ace4e0", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.387825664Z", "endTime": "2021-04-20T20:33:43.460932608Z", "durationInNanos": 73106944, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60994, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "2bacaf900ae368c7"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "2bacaf900ae368c7", "traceState": "", "parentSpanId": "5d8912365e6688f3", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.845935616Z", "endTime": "2021-04-20T20:33:43.847112448Z", "durationInNanos": 1176832, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "cf38f810fff59bb3"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "cf38f810fff59bb3", "traceState": "", "parentSpanId": "5d8912365e6688f3", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.850872832Z", "endTime": "2021-04-20T20:33:43.871734272Z", "durationInNanos": 20861440, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "37628f7fdcf79dbb"}}
-{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "37628f7fdcf79dbb", "traceState": "", "parentSpanId": "cf2a67c23dc23bab", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.791471041Z", "endTime": "2021-04-20T20:33:39.792596934Z", "durationInNanos": 1125893, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "dd0a9b2bcbdcdbb6"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "dd0a9b2bcbdcdbb6", "traceState": "", "parentSpanId": "a981fd033e3a7491", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.248690371Z", "endTime": "2021-04-20T20:33:41.249957195Z", "durationInNanos": 1266824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "3230880363166a80"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "3230880363166a80", "traceState": "", "parentSpanId": "f405f62e61d4181f", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.643464807Z", "endTime": "2021-04-20T20:33:42.644564500Z", "durationInNanos": 1099693, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "1fbcd1691508fa92"}}
-{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "1fbcd1691508fa92", "traceState": "", "parentSpanId": "c519a467435258a0", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.859001828Z", "endTime": "2021-04-20T20:33:40.860862299Z", "durationInNanos": 1860471, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57798, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "570073e77e68be9d"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "570073e77e68be9d", "traceState": "", "parentSpanId": "72fd9aa427e26550", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.185529088Z", "endTime": "2021-04-20T20:33:44.218529024Z", "durationInNanos": 32999936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "2311bcf70d68331c"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "2311bcf70d68331c", "traceState": "", "parentSpanId": "c63088be2f211cf7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.277222400Z", "endTime": "2021-04-20T20:33:44.312690432Z", "durationInNanos": 35468032, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58648, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "885e54cf2034b9f4"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "885e54cf2034b9f4", "traceState": "", "parentSpanId": "104a8f2719108aaf", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.181856512Z", "endTime": "2021-04-20T20:33:44.328167424Z", "durationInNanos": 146310912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "104a8f2719108aaf"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "104a8f2719108aaf", "traceState": "", "parentSpanId": "c85e5dec4106a06a", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.181052672Z", "endTime": "2021-04-20T20:33:44.330511104Z", "durationInNanos": 149458432, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32782, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "504e26f11e5bb1ae"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "504e26f11e5bb1ae", "traceState": "", "parentSpanId": "0ee38170cee8fb5c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.594721792Z", "endTime": "2021-04-20T20:33:44.599331328Z", "durationInNanos": 4609536, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "93047965b18da903"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "93047965b18da903", "traceState": "", "parentSpanId": "7359981596903c3f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.966868736Z", "endTime": "2021-04-20T20:33:44.989101312Z", "durationInNanos": 22232576, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "9ca0bf86196899bc"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "9ca0bf86196899bc", "traceState": "", "parentSpanId": "ead17a7f0d4e34ed", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.943505664Z", "endTime": "2021-04-20T20:33:45.011987456Z", "durationInNanos": 68481792, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "92e84113ddc59da5"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "92e84113ddc59da5", "traceState": "", "parentSpanId": "dcf70445f2a2cd40", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.654626048Z", "endTime": "2021-04-20T20:33:45.655334912Z", "durationInNanos": 708864, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "dcf70445f2a2cd40"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "dcf70445f2a2cd40", "traceState": "", "parentSpanId": "0c64ae315abfd656", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.634566144Z", "endTime": "2021-04-20T20:33:45.659138816Z", "durationInNanos": 24572672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "0c64ae315abfd656"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "0c64ae315abfd656", "traceState": "", "parentSpanId": "cf25277706dc2439", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.633674752Z", "endTime": "2021-04-20T20:33:45.662507776Z", "durationInNanos": 28833024, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58692, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9bdbac7482af31f3"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "9bdbac7482af31f3", "traceState": "", "parentSpanId": "ded3687b9758bf59", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.584570112Z", "endTime": "2021-04-20T20:33:45.719764480Z", "durationInNanos": 135194368, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32832, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "8e8e5e8bd88c11b5"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "8e8e5e8bd88c11b5", "traceState": "", "parentSpanId": "69af53e3494bca1c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.943921408Z", "endTime": "2021-04-20T20:33:45.965064192Z", "durationInNanos": 21142784, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "69af53e3494bca1c"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "69af53e3494bca1c", "traceState": "", "parentSpanId": "3a025025e0a3b1fa", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.913632256Z", "endTime": "2021-04-20T20:33:45.968429568Z", "durationInNanos": 54797312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ea4bcbaf2a9a6fa3"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "ea4bcbaf2a9a6fa3", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.907184128Z", "endTime": "2021-04-20T20:33:45.997188352Z", "durationInNanos": 90004224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "5edd047783ce31e6"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "5edd047783ce31e6", "traceState": "", "parentSpanId": "9a880188bcb44cda", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.196210944Z", "endTime": "2021-04-20T20:33:46.228526592Z", "durationInNanos": 32315648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58722, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "6f7eafee7d68115c"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "6f7eafee7d68115c", "traceState": "", "parentSpanId": "203faf4d95696dc4", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.240107008Z", "endTime": "2021-04-20T20:33:46.267194368Z", "durationInNanos": 27087360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "22b1d496a103d5d4"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "22b1d496a103d5d4", "traceState": "", "parentSpanId": "30652f6f8b511470", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.151774720Z", "endTime": "2021-04-20T20:33:46.278444288Z", "durationInNanos": 126669568, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "e270a32c23bb3d64"}}
-{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "e270a32c23bb3d64", "traceState": "", "parentSpanId": "b9eb99e7f12a273f", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.505004800Z", "endTime": "2021-04-20T20:33:46.555533056Z", "durationInNanos": 50528256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "a3ff3a8683434406"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "a3ff3a8683434406", "traceState": "", "parentSpanId": "c78ae9d1aa24d379", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.821765888Z", "endTime": "2021-04-20T20:33:46.822455808Z", "durationInNanos": 689920, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "63f9d7eb1b86d29a"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "63f9d7eb1b86d29a", "traceState": "", "parentSpanId": "43dc7bc2e05bfa0f", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.800928512Z", "endTime": "2021-04-20T20:33:46.835864064Z", "durationInNanos": 34935552, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58744, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "43dc7bc2e05bfa0f"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "43dc7bc2e05bfa0f", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.798465280Z", "endTime": "2021-04-20T20:33:46.840932096Z", "durationInNanos": 42466816, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "fddac8b6501344bf"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "fddac8b6501344bf", "traceState": "", "parentSpanId": "3b2b065511029f95", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.866892288Z", "endTime": "2021-04-20T20:33:46.867537408Z", "durationInNanos": 645120, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "759ba13f98ab3fc6"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "759ba13f98ab3fc6", "traceState": "", "parentSpanId": "fa4a423fd5b1089d", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.846178304Z", "endTime": "2021-04-20T20:33:46.874823424Z", "durationInNanos": 28645120, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58748, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "fa4a423fd5b1089d"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "fa4a423fd5b1089d", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.843851264Z", "endTime": "2021-04-20T20:33:46.879571200Z", "durationInNanos": 35719936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f0aeb9700f457880"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "f0aeb9700f457880", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.882574848Z", "endTime": "2021-04-20T20:33:46.918776576Z", "durationInNanos": 36201728, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "51c0b6f4525f8ce7"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "51c0b6f4525f8ce7", "traceState": "", "parentSpanId": "46804b074d510e22", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.798070016Z", "endTime": "2021-04-20T20:33:46.929501952Z", "durationInNanos": 131431936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "4fb9849a6b80b6f2"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "4fb9849a6b80b6f2", "traceState": "", "parentSpanId": "8d4b7a48cb7ee8e9", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.263351552Z", "endTime": "2021-04-20T20:33:47.264209664Z", "durationInNanos": 858112, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "f78dbd14cda8862e"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "f78dbd14cda8862e", "traceState": "", "parentSpanId": "b974c6840493462f", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.230816768Z", "endTime": "2021-04-20T20:33:47.274358784Z", "durationInNanos": 43542016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58768, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "3e1ca23a1316a089"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "3e1ca23a1316a089", "traceState": "", "parentSpanId": "9995da51cebe7887", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.188528128Z", "endTime": "2021-04-20T20:33:47.323207424Z", "durationInNanos": 134679296, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "35a5641a51a07620"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "35a5641a51a07620", "traceState": "", "parentSpanId": "f707df9bafaf7974", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.184227840Z", "endTime": "2021-04-20T20:33:47.335330816Z", "durationInNanos": 151102976, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60014, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "5b03c5aa49169de7"}}
-{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "5b03c5aa49169de7", "traceState": "", "parentSpanId": "153b191f5bba208f", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.480588800Z", "endTime": "2021-04-20T20:33:47.490298112Z", "durationInNanos": 9709312, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32926, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
-{ "index":{"_id": "a0333ab0c0fb425e"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "a0333ab0c0fb425e", "traceState": "", "parentSpanId": "e36a01c310db6537", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.777365760Z", "endTime": "2021-04-20T20:33:47.806075648Z", "durationInNanos": 28709888, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58788, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e36a01c310db6537"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "e36a01c310db6537", "traceState": "", "parentSpanId": "b7db1195f7777f37", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.775088640Z", "endTime": "2021-04-20T20:33:47.810972160Z", "durationInNanos": 35883520, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "246d5a128abc0323"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "246d5a128abc0323", "traceState": "", "parentSpanId": "0adbc627a3ff01db", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.856003328Z", "endTime": "2021-04-20T20:33:47.880837376Z", "durationInNanos": 24834048, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "b7db1195f7777f37"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "b7db1195f7777f37", "traceState": "", "parentSpanId": "48c5f132edd1dce1", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.774677248Z", "endTime": "2021-04-20T20:33:47.900943872Z", "durationInNanos": 126266624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "8d13c5fb5cb910ab"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "8d13c5fb5cb910ab", "traceState": "", "parentSpanId": "ebfe1ad9b112ca2a", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.771634688Z", "endTime": "2021-04-20T20:33:47.907790080Z", "durationInNanos": 136155392, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "36362df397ac500d"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "36362df397ac500d", "traceState": "", "parentSpanId": "29749eb615c7cf76", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.093012480Z", "endTime": "2021-04-20T20:33:48.128655104Z", "durationInNanos": 35642624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "29749eb615c7cf76"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "29749eb615c7cf76", "traceState": "", "parentSpanId": "9a8427df12be8522", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.092771840Z", "endTime": "2021-04-20T20:33:48.138572032Z", "durationInNanos": 45800192, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "60b801fae48abf9b"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "60b801fae48abf9b", "traceState": "", "parentSpanId": "3e916e70241c5f31", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.089861120Z", "endTime": "2021-04-20T20:33:48.145265920Z", "durationInNanos": 55404800, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "fc52a63dddb6c78e"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "fc52a63dddb6c78e", "traceState": "", "parentSpanId": "a7ef8140aea6adc9", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.767165440Z", "endTime": "2021-04-20T20:33:48.771305728Z", "durationInNanos": 4140288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a7ef8140aea6adc9"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "a7ef8140aea6adc9", "traceState": "", "parentSpanId": "f0839669f041b029", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.727941632Z", "endTime": "2021-04-20T20:33:48.774041600Z", "durationInNanos": 46099968, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "e038c5aba828ea58"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "e038c5aba828ea58", "traceState": "", "parentSpanId": "658da2faba59acd9", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.023798016Z", "endTime": "2021-04-20T20:33:49.024448256Z", "durationInNanos": 650240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "81de5d2c6aa0859e"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "81de5d2c6aa0859e", "traceState": "", "parentSpanId": "0c1e1c234af592e4", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.042136064Z", "endTime": "2021-04-20T20:33:49.071018496Z", "durationInNanos": 28882432, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58840, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e25b39ceacb30b75"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "e25b39ceacb30b75", "traceState": "", "parentSpanId": "fec494ea1cd015e3", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.301444832Z", "endTime": "2021-04-20T20:33:45.302604111Z", "durationInNanos": 1159279, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "a1339d62f81ccd32"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "a1339d62f81ccd32", "traceState": "", "parentSpanId": "2ac8b4cda3c0f1f9", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.711423559Z", "endTime": "2021-04-20T20:33:45.712615012Z", "durationInNanos": 1191453, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "fdbb1f2f7b488e87"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "fdbb1f2f7b488e87", "traceState": "", "parentSpanId": "75432a4e251c77c6", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.982518483Z", "endTime": "2021-04-20T20:33:45.983665774Z", "durationInNanos": 1147291, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "3ee4a8601f798b23"}}
-{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "3ee4a8601f798b23", "traceState": "", "parentSpanId": "74dbc2be658b50d8", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.456438616Z", "endTime": "2021-04-20T20:33:48.457460497Z", "durationInNanos": 1021881, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "552e8512fb52ccb5"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "552e8512fb52ccb5", "traceState": "", "parentSpanId": "504e26f11e5bb1ae", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.596001537Z", "endTime": "2021-04-20T20:33:44.597771774Z", "durationInNanos": 1770237, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57902, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "11f0fc7fd6fc8ef7"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "11f0fc7fd6fc8ef7", "traceState": "", "parentSpanId": "b45e32302ccd4555", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.133001853Z", "endTime": "2021-04-20T20:33:48.134747430Z", "durationInNanos": 1745577, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58050, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "6436b12426e22058"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "6436b12426e22058", "traceState": "", "parentSpanId": "fc52a63dddb6c78e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.769001550Z", "endTime": "2021-04-20T20:33:48.770509554Z", "durationInNanos": 1508004, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58070, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "be8803ab43db27ca"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "be8803ab43db27ca", "traceState": "", "parentSpanId": "1ca472e346ee563d", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.084217344Z", "endTime": "2021-04-20T20:33:49.111971584Z", "durationInNanos": 27754240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "27d4fe07134ea308"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "27d4fe07134ea308", "traceState": "", "parentSpanId": "6de234553c12cdd0", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.999261952Z", "endTime": "2021-04-20T20:33:49.132644864Z", "durationInNanos": 133382912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32980, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7ab01768aa773b1c"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "7ab01768aa773b1c", "traceState": "", "parentSpanId": "c7c175f4366ce130", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.318971392Z", "endTime": "2021-04-20T20:33:49.340009216Z", "durationInNanos": 21037824, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "1e69961f46e59586"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "1e69961f46e59586", "traceState": "", "parentSpanId": "73d85e6251f927f6", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.288094720Z", "endTime": "2021-04-20T20:33:49.346589952Z", "durationInNanos": 58495232, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58854, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a4790e6461fa0d5d"}}
-{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "a4790e6461fa0d5d", "traceState": "", "parentSpanId": "8979ca2f03690516", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.284838912Z", "endTime": "2021-04-20T20:33:49.364374528Z", "durationInNanos": 79535616, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32998, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c4eb12c87b56bbaf"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "c4eb12c87b56bbaf", "traceState": "", "parentSpanId": "b7362733de8bfa9c", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.527205120Z", "endTime": "2021-04-20T20:33:49.551947008Z", "durationInNanos": 24741888, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:49.551908096Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "b7362733de8bfa9c"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "b7362733de8bfa9c", "traceState": "", "parentSpanId": "9be2ff98ca6d0261", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.526326272Z", "endTime": "2021-04-20T20:33:49.556307200Z", "durationInNanos": 29980928, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58866, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "9be2ff98ca6d0261"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "9be2ff98ca6d0261", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.523984384Z", "endTime": "2021-04-20T20:33:49.561157120Z", "durationInNanos": 37172736, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "bb41f245f32492e4"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "bb41f245f32492e4", "traceState": "", "parentSpanId": "6025c3c1f9ee5054", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.517226496Z", "endTime": "2021-04-20T20:33:49.661549056Z", "durationInNanos": 144322560, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "2c3fe2ecd7602e0b"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "2c3fe2ecd7602e0b", "traceState": "", "parentSpanId": "ecc02e73350ce790", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.850896896Z", "endTime": "2021-04-20T20:33:49.902683392Z", "durationInNanos": 51786496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58882, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "3b0e8b5888901f7b"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "3b0e8b5888901f7b", "traceState": "", "parentSpanId": "de9f1128bf12b7b9", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.910390784Z", "endTime": "2021-04-20T20:33:49.915180544Z", "durationInNanos": 4789760, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c6621138316a73b8"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "c6621138316a73b8", "traceState": "", "parentSpanId": "6f5a1a55f4c950f0", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.221707008Z", "endTime": "2021-04-20T20:33:50.250929920Z", "durationInNanos": 29222912, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58900, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "6f5a1a55f4c950f0"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "6f5a1a55f4c950f0", "traceState": "", "parentSpanId": "d18bdbb97967e206", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.219329024Z", "endTime": "2021-04-20T20:33:50.255876352Z", "durationInNanos": 36547328, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d18bdbb97967e206"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "d18bdbb97967e206", "traceState": "", "parentSpanId": "3b639def2d6ec40f", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.141257984Z", "endTime": "2021-04-20T20:33:50.267165184Z", "durationInNanos": 125907200, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "6a539e36635daed1"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "6a539e36635daed1", "traceState": "", "parentSpanId": "13bed71d66dcc038", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.480547328Z", "endTime": "2021-04-20T20:33:50.509742080Z", "durationInNanos": 29194752, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58912, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e282094546b98e61"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "e282094546b98e61", "traceState": "", "parentSpanId": "3a565f7129913c17", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.477368832Z", "endTime": "2021-04-20T20:33:50.527277568Z", "durationInNanos": 49908736, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33056, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c80dc4c948d060d2"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "c80dc4c948d060d2", "traceState": "", "parentSpanId": "7e0f8516534902ba", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.727715584Z", "endTime": "2021-04-20T20:33:50.764667904Z", "durationInNanos": 36952320, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e6af061aa53f5621"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "e6af061aa53f5621", "traceState": "", "parentSpanId": "ecc0e3f8be5250dd", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.812071936Z", "endTime": "2021-04-20T20:33:50.836778496Z", "durationInNanos": 24706560, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "268c00835c4cc7ac"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "268c00835c4cc7ac", "traceState": "", "parentSpanId": "7e0f8516534902ba", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.848304640Z", "endTime": "2021-04-20T20:33:50.852795392Z", "durationInNanos": 4490752, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "aaa75101bed92d1a"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "aaa75101bed92d1a", "traceState": "", "parentSpanId": "e9893407bba95bf0", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.138495232Z", "endTime": "2021-04-20T20:33:51.166544384Z", "durationInNanos": 28049152, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58940, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "bf2482df930950bb"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "bf2482df930950bb", "traceState": "", "parentSpanId": "0068b98ffc99f9ea", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.135342336Z", "endTime": "2021-04-20T20:33:51.183588864Z", "durationInNanos": 48246528, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33084, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "93330439f7f89167"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "93330439f7f89167", "traceState": "", "parentSpanId": "9b81a0201a53b84c", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.683300864Z", "endTime": "2021-04-20T20:33:51.708692992Z", "durationInNanos": 25392128, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "a9ed253bbf36e70e"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "a9ed253bbf36e70e", "traceState": "", "parentSpanId": "a5a0c83096c8fa20", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.016589056Z", "endTime": "2021-04-20T20:33:52.017283328Z", "durationInNanos": 694272, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "6576e80159aee6b8"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "6576e80159aee6b8", "traceState": "", "parentSpanId": "71e8453fb0ed5faf", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.953919744Z", "endTime": "2021-04-20T20:33:52.078983680Z", "durationInNanos": 125063936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "f8aedbcbab807a78"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "f8aedbcbab807a78", "traceState": "", "parentSpanId": "ed7415d8c9c25969", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.207869440Z", "endTime": "2021-04-20T20:33:52.278209280Z", "durationInNanos": 70339840, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ed7415d8c9c25969"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "ed7415d8c9c25969", "traceState": "", "parentSpanId": "0db04213ba31cb79", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.207073792Z", "endTime": "2021-04-20T20:33:52.280379136Z", "durationInNanos": 73305344, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33132, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "702250f453a02be6"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "702250f453a02be6", "traceState": "", "parentSpanId": "4acae5e4234f52f8", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.496930560Z", "endTime": "2021-04-20T20:33:52.623046656Z", "durationInNanos": 126116096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "84584d9e50950ea5"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "84584d9e50950ea5", "traceState": "", "parentSpanId": "d85ef60c6b05ea1e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.815784192Z", "endTime": "2021-04-20T20:33:52.820143872Z", "durationInNanos": 4359680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e0514a47c90c0ead"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "e0514a47c90c0ead", "traceState": "", "parentSpanId": "d620278613ba1273", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.674479616Z", "endTime": "2021-04-20T20:33:52.825445632Z", "durationInNanos": 150966016, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33160, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "dfd4cc33b9f49d74"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "dfd4cc33b9f49d74", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.672014080Z", "endTime": "2021-04-20T20:33:52.833018624Z", "durationInNanos": 161004544, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "84e395f144998c01"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "84e395f144998c01", "traceState": "", "parentSpanId": "b6b76ad0ea7a18e0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.949800192Z", "endTime": "2021-04-20T20:33:52.951031040Z", "durationInNanos": 1230848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "7e35a93ae1f1d3dc"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "7e35a93ae1f1d3dc", "traceState": "", "parentSpanId": "a77612b8a846894a", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.926126336Z", "endTime": "2021-04-20T20:33:53.003924224Z", "durationInNanos": 77797888, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33178, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a77612b8a846894a"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "a77612b8a846894a", "traceState": "", "parentSpanId": "36bf8ffe6bfab949", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.923979776Z", "endTime": "2021-04-20T20:33:53.008655360Z", "durationInNanos": 84675584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "36bf8ffe6bfab949"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "36bf8ffe6bfab949", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.923733504Z", "endTime": "2021-04-20T20:33:53.011512832Z", "durationInNanos": 87779328, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "057ca06095200357"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "057ca06095200357", "traceState": "", "parentSpanId": "ab2cfda3f66cd29a", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.258444032Z", "endTime": "2021-04-20T20:33:53.288954112Z", "durationInNanos": 30510080, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59050, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "66a2144a58008463"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "66a2144a58008463", "traceState": "", "parentSpanId": "79e7e8f4a6b9cfd6", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.211445504Z", "endTime": "2021-04-20T20:33:53.348402432Z", "durationInNanos": 136956928, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7c1551bf8ecff1e9"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "7c1551bf8ecff1e9", "traceState": "", "parentSpanId": "1baf1e42d2eaae2a", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.432177920Z", "endTime": "2021-04-20T20:33:53.488074240Z", "durationInNanos": 55896320, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59064, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d074c89b98685510"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "d074c89b98685510", "traceState": "", "parentSpanId": "7b337ab41060959b", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.912560857Z", "endTime": "2021-04-20T20:33:49.913841981Z", "durationInNanos": 1281124, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "8d1a3be816dc5afe"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "8d1a3be816dc5afe", "traceState": "", "parentSpanId": "391c448e02ace429", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.073446568Z", "endTime": "2021-04-20T20:33:52.074477704Z", "durationInNanos": 1031136, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "92b74f59ddd54783"}}
-{ "traceId": "588f0d3438674277899b1f0bf2f2ebf2", "spanId": "92b74f59ddd54783", "traceState": "", "parentSpanId": "", "name": "mysql", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:15.007993856Z", "endTime": "2021-04-20T20:33:15.024957696Z", "durationInNanos": 16963840, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "mysql", "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "", "span.attributes.db@statement": "CREATE TABLE `User_Carts` ( `ItemId` varchar(16) NOT NULL, `TotalQty` int(11) NOT NULL, PRIMARY KEY (`ItemId`)) ENGINE=InnoDB", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "25af21b469c032b3"}}
-{ "traceId": "64398afff83d4ce40feb342b493d03cf", "spanId": "25af21b469c032b3", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:17.441215232Z", "endTime": "2021-04-20T20:33:17.444359680Z", "durationInNanos": 3144448, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 47996, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
-{ "index":{"_id": "6c89443d5e23abf3"}}
-{ "traceId": "df5948afbb8aa0bdd587a5b81d7589da", "spanId": "6c89443d5e23abf3", "traceState": "", "parentSpanId": "c9ffe4c0af278e39", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:28.392941824Z", "endTime": "2021-04-20T20:33:28.467089152Z", "durationInNanos": 74147328, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "96e7fdedd82ab53c"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "96e7fdedd82ab53c", "traceState": "", "parentSpanId": "2c122c9d8977d38d", "name": "verify_login", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:32.542609152Z", "endTime": "2021-04-20T20:33:32.542644224Z", "durationInNanos": 35072, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "71869e6acbd9b84e"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "71869e6acbd9b84e", "traceState": "", "parentSpanId": "6921db03f367dc79", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:32.548511744Z", "endTime": "2021-04-20T20:33:32.614019584Z", "durationInNanos": 65507840, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/read_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "39d9f21d9865f9e6"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "39d9f21d9865f9e6", "traceState": "", "parentSpanId": "", "name": "load_main_screen", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:32.538752Z", "endTime": "2021-04-20T20:33:32.652837376Z", "durationInNanos": 114085376, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "load_main_screen", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "2a1b45c16eaad09c"}}
-{ "traceId": "a80cb852f0c27762cfa923836bc5fe88", "spanId": "2a1b45c16eaad09c", "traceState": "", "parentSpanId": "9ba40f97c2ae86a7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:33.447434240Z", "endTime": "2021-04-20T20:33:33.454592512Z", "durationInNanos": 7158272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9ba40f97c2ae86a7"}}
-{ "traceId": "a80cb852f0c27762cfa923836bc5fe88", "spanId": "9ba40f97c2ae86a7", "traceState": "", "parentSpanId": "daf5a14650228970", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:33.446325504Z", "endTime": "2021-04-20T20:33:33.457898240Z", "durationInNanos": 11572736, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60706, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
-{ "index":{"_id": "84fe46385d17b02c"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "84fe46385d17b02c", "traceState": "", "parentSpanId": "e1bc8cfc3ceb0aaf", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.601002072Z", "endTime": "2021-04-20T20:33:32.603410081Z", "durationInNanos": 2408009, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57560, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "2a5ae161952463e2"}}
-{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "2a5ae161952463e2", "traceState": "", "parentSpanId": "ff013ccfd9d58cec", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.638002124Z", "endTime": "2021-04-20T20:33:32.640473313Z", "durationInNanos": 2471189, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57564, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "d4255abf68ac0402"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "d4255abf68ac0402", "traceState": "", "parentSpanId": "31a0c82890fa754b", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.222288128Z", "endTime": "2021-04-20T20:33:34.254911488Z", "durationInNanos": 32623360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "be5b2f7a197c64cf"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "be5b2f7a197c64cf", "traceState": "", "parentSpanId": "97aa186489e038e0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.219140864Z", "endTime": "2021-04-20T20:33:34.263220992Z", "durationInNanos": 44080128, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e46a02e7b9ed8ecf"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "e46a02e7b9ed8ecf", "traceState": "", "parentSpanId": "c17b37664943c0a0", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.269251584Z", "endTime": "2021-04-20T20:33:34.300863232Z", "durationInNanos": 31611648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "c17b37664943c0a0"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "c17b37664943c0a0", "traceState": "", "parentSpanId": "e5fd4823e84df1a0", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.268306688Z", "endTime": "2021-04-20T20:33:34.304210944Z", "durationInNanos": 35904256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58340, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "55d7f80c6aff4ec7"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "55d7f80c6aff4ec7", "traceState": "", "parentSpanId": "97aa186489e038e0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.312219392Z", "endTime": "2021-04-20T20:33:34.354283520Z", "durationInNanos": 42064128, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c0cb4dc5b7b1db59"}}
-{ "traceId": "9cc5c0acce9b9acc05b1c8d082709609", "spanId": "c0cb4dc5b7b1db59", "traceState": "", "parentSpanId": "16d6fb920c980921", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.231047680Z", "endTime": "2021-04-20T20:33:35.236322816Z", "durationInNanos": 5275136, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "6f3b8af3574d67d8"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "6f3b8af3574d67d8", "traceState": "", "parentSpanId": "d7d09b29635c42d0", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.667787520Z", "endTime": "2021-04-20T20:33:35.699713792Z", "durationInNanos": 31926272, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1cfde34b0e64708d"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "1cfde34b0e64708d", "traceState": "", "parentSpanId": "16a087ca75a1c1ae", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.714154496Z", "endTime": "2021-04-20T20:33:35.744516352Z", "durationInNanos": 30361856, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "c607c3f259c8a65b"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "c607c3f259c8a65b", "traceState": "", "parentSpanId": "bb9e8ac613f9c314", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.778753792Z", "endTime": "2021-04-20T20:33:35.779580160Z", "durationInNanos": 826368, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "bb9e8ac613f9c314"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "bb9e8ac613f9c314", "traceState": "", "parentSpanId": "f756b2ab52d63952", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.758739968Z", "endTime": "2021-04-20T20:33:35.789022208Z", "durationInNanos": 30282240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "f19d16050494663f"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "f19d16050494663f", "traceState": "", "parentSpanId": "7d7dc4421190f8f1", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.755664896Z", "endTime": "2021-04-20T20:33:35.797313792Z", "durationInNanos": 41648896, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "4d9ad162398612ca"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "4d9ad162398612ca", "traceState": "", "parentSpanId": "db173bc10299861f", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.071021056Z", "endTime": "2021-04-20T20:33:36.151107328Z", "durationInNanos": 80086272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "de9f05334009f30f"}}
-{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "de9f05334009f30f", "traceState": "", "parentSpanId": "9e8cf0411a1b61f8", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.069997312Z", "endTime": "2021-04-20T20:33:36.166950656Z", "durationInNanos": 96953344, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60770, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7aa2821664832544"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "7aa2821664832544", "traceState": "", "parentSpanId": "bb004c0fd4fe0458", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.512588032Z", "endTime": "2021-04-20T20:33:36.513520384Z", "durationInNanos": 932352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "b515153fd36d853a"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "b515153fd36d853a", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.489266944Z", "endTime": "2021-04-20T20:33:36.528014080Z", "durationInNanos": 38747136, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "41b5cf2346593387"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "41b5cf2346593387", "traceState": "", "parentSpanId": "9835a28e768c1334", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.533314304Z", "endTime": "2021-04-20T20:33:36.564330496Z", "durationInNanos": 31016192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58410, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "937fb8345b252adb"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "937fb8345b252adb", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.614607616Z", "endTime": "2021-04-20T20:33:36.620131584Z", "durationInNanos": 5523968, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b5eb104616d427e5"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "b5eb104616d427e5", "traceState": "", "parentSpanId": "702b587891032394", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.488680960Z", "endTime": "2021-04-20T20:33:36.622967040Z", "durationInNanos": 134286080, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "702b587891032394"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "702b587891032394", "traceState": "", "parentSpanId": "375cb3ef27c46997", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.487866112Z", "endTime": "2021-04-20T20:33:36.625204992Z", "durationInNanos": 137338880, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48158, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d3911d8b057539bb"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "d3911d8b057539bb", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.481575424Z", "endTime": "2021-04-20T20:33:36.650631936Z", "durationInNanos": 169056512, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "e71642d4deaf046a"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "e71642d4deaf046a", "traceState": "", "parentSpanId": "3d1fe27819634f95", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.024145664Z", "endTime": "2021-04-20T20:33:37.047470592Z", "durationInNanos": 23324928, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "c978b33c59a54196"}}
-{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "c978b33c59a54196", "traceState": "", "parentSpanId": "a7fcdbe2bf6d6d75", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.062592256Z", "endTime": "2021-04-20T20:33:37.067854080Z", "durationInNanos": 5261824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a00565be802b54b4"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "a00565be802b54b4", "traceState": "", "parentSpanId": "dfbc0ecddf9324b7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.480550912Z", "endTime": "2021-04-20T20:33:37.481288960Z", "durationInNanos": 738048, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "67e273104da42d94"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "67e273104da42d94", "traceState": "", "parentSpanId": "e1f71dfda83b894c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.527881984Z", "endTime": "2021-04-20T20:33:37.528583168Z", "durationInNanos": 701184, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "965c5d8b0b6276c0"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "965c5d8b0b6276c0", "traceState": "", "parentSpanId": "67a615bb3d2aef86", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.500228096Z", "endTime": "2021-04-20T20:33:37.541810176Z", "durationInNanos": 41582080, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "6bf6fc5237230c42"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "6bf6fc5237230c42", "traceState": "", "parentSpanId": "1eda1c86b53778f8", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:37.404817152Z", "endTime": "2021-04-20T20:33:37.554722304Z", "durationInNanos": 149905152, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60812, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "91921c51d51c884f"}}
-{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "91921c51d51c884f", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.806868480Z", "endTime": "2021-04-20T20:33:37.807457792Z", "durationInNanos": 589312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "8aa7fc60f5c7d6b9"}}
-{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "8aa7fc60f5c7d6b9", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.810970624Z", "endTime": "2021-04-20T20:33:37.811611392Z", "durationInNanos": 640768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "6e1dcac7d59fac91"}}
-{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "6e1dcac7d59fac91", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.823713280Z", "endTime": "2021-04-20T20:33:37.843032832Z", "durationInNanos": 19319552, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "921202e7eca9c5be"}}
-{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "921202e7eca9c5be", "traceState": "", "parentSpanId": "3b8fd25db26f6336", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.784199936Z", "endTime": "2021-04-20T20:33:37.854919424Z", "durationInNanos": 70719488, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d65f4119e3d35c6f"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "d65f4119e3d35c6f", "traceState": "", "parentSpanId": "b8440d5b592650f2", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.157860352Z", "endTime": "2021-04-20T20:33:38.185885952Z", "durationInNanos": 28025600, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1b26c8058d3cd7b6"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "1b26c8058d3cd7b6", "traceState": "", "parentSpanId": "2fa45786a2e85af4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.238149632Z", "endTime": "2021-04-20T20:33:38.277396480Z", "durationInNanos": 39246848, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "952b9f3e06ee5533"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "952b9f3e06ee5533", "traceState": "", "parentSpanId": "45ff7de69dace1d6", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.153484288Z", "endTime": "2021-04-20T20:33:38.292515584Z", "durationInNanos": 139031296, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48218, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "45ff7de69dace1d6"}}
-{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "45ff7de69dace1d6", "traceState": "", "parentSpanId": "67c3240b15bfc41a", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.151339520Z", "endTime": "2021-04-20T20:33:38.297237504Z", "durationInNanos": 145897984, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "03699d100410017f"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "03699d100410017f", "traceState": "", "parentSpanId": "e65cbb55e80306bb", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.578456320Z", "endTime": "2021-04-20T20:33:38.605642496Z", "durationInNanos": 27186176, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "7d1c23fc87c00b35"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "7d1c23fc87c00b35", "traceState": "", "parentSpanId": "d3449d96433ef65b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.641069568Z", "endTime": "2021-04-20T20:33:38.641892096Z", "durationInNanos": 822528, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "07b4d48cb660e9cc"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "07b4d48cb660e9cc", "traceState": "", "parentSpanId": "bde992160f31f631", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.556106240Z", "endTime": "2021-04-20T20:33:38.737072384Z", "durationInNanos": 180966144, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59740, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9aa1509f5e191508"}}
-{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "9aa1509f5e191508", "traceState": "", "parentSpanId": "7b78d2bea411b2fe", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.359700428Z", "endTime": "2021-04-20T20:33:34.361556108Z", "durationInNanos": 1855680, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "e1dfd31ab1a2b193"}}
-{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "e1dfd31ab1a2b193", "traceState": "", "parentSpanId": "7145d5e8e15acfb7", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.745707353Z", "endTime": "2021-04-20T20:33:34.747566050Z", "durationInNanos": 1858697, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "2751e720b71a60a4"}}
-{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "2751e720b71a60a4", "traceState": "", "parentSpanId": "31f5aad7d2ea1fcb", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.547512262Z", "endTime": "2021-04-20T20:33:37.548630086Z", "durationInNanos": 1117824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "4b7e5e41b0e7fd04"}}
-{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "4b7e5e41b0e7fd04", "traceState": "", "parentSpanId": "d11da5c9c394bde8", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:35.802002385Z", "endTime": "2021-04-20T20:33:35.804283108Z", "durationInNanos": 2280723, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57628, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "74e54ea9fdbf735f"}}
-{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "74e54ea9fdbf735f", "traceState": "", "parentSpanId": "900fb4b6271869ab", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.635002138Z", "endTime": "2021-04-20T20:33:36.637319816Z", "durationInNanos": 2317678, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57660, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "75b7e359c49acf55"}}
-{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "75b7e359c49acf55", "traceState": "", "parentSpanId": "02d508caf899367c", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.562002009Z", "endTime": "2021-04-20T20:33:38.563741689Z", "durationInNanos": 1739680, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57730, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "e1300ec1802ecc3c"}}
-{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "e1300ec1802ecc3c", "traceState": "", "parentSpanId": "913de07418b7eed7", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.931558144Z", "endTime": "2021-04-20T20:33:38.984496640Z", "durationInNanos": 52938496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "8c03b29267586319"}}
-{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "8c03b29267586319", "traceState": "", "parentSpanId": "a03543bce133747e", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.927511808Z", "endTime": "2021-04-20T20:33:39.006228736Z", "durationInNanos": 78716928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "f5fe5f65731875d1"}}
-{ "traceId": "a371f923b4967cb722e563725cc2a91d", "spanId": "f5fe5f65731875d1", "traceState": "", "parentSpanId": "3ed24d73086e3a5c", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.432419840Z", "endTime": "2021-04-20T20:33:39.482711808Z", "durationInNanos": 50291968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58524, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "3ed24d73086e3a5c"}}
-{ "traceId": "a371f923b4967cb722e563725cc2a91d", "spanId": "3ed24d73086e3a5c", "traceState": "", "parentSpanId": "e2ca5dbb18427bbc", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:39.430222336Z", "endTime": "2021-04-20T20:33:39.487606272Z", "durationInNanos": 57383936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "8eafdbb08ef33fac"}}
-{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "8eafdbb08ef33fac", "traceState": "", "parentSpanId": "f69d6486408d5ceb", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.753607936Z", "endTime": "2021-04-20T20:33:39.778727168Z", "durationInNanos": 25119232, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "6f9b9156dc914a59"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "6f9b9156dc914a59", "traceState": "", "parentSpanId": "027e1f4686076d5e", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.251508736Z", "endTime": "2021-04-20T20:33:40.252164096Z", "durationInNanos": 655360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "7052b8e18f95d355"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "7052b8e18f95d355", "traceState": "", "parentSpanId": "669d2b7892e6854c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.291585280Z", "endTime": "2021-04-20T20:33:40.296150784Z", "durationInNanos": 4565504, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "9253cd2f27e55a6f"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "9253cd2f27e55a6f", "traceState": "", "parentSpanId": "517b250c6b019d50", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.227543040Z", "endTime": "2021-04-20T20:33:40.301341184Z", "durationInNanos": 73798144, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60920, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "517b250c6b019d50"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "517b250c6b019d50", "traceState": "", "parentSpanId": "883dff4473fb6cb2", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.225460992Z", "endTime": "2021-04-20T20:33:40.305951232Z", "durationInNanos": 80490240, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "883dff4473fb6cb2"}}
-{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "883dff4473fb6cb2", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.225210368Z", "endTime": "2021-04-20T20:33:40.308697600Z", "durationInNanos": 83487232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1bf5449206413fa6"}}
-{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "1bf5449206413fa6", "traceState": "", "parentSpanId": "8ac46543c6308b05", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.794464Z", "endTime": "2021-04-20T20:33:40.866789376Z", "durationInNanos": 72325376, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60930, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a4ba523cda11d1d3"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "a4ba523cda11d1d3", "traceState": "", "parentSpanId": "d10b1e24cdce1630", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.182262528Z", "endTime": "2021-04-20T20:33:41.253643520Z", "durationInNanos": 71380992, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1c5f7bbfcfc2fd9c"}}
-{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "1c5f7bbfcfc2fd9c", "traceState": "", "parentSpanId": "", "name": "client_pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.179067136Z", "endTime": "2021-04-20T20:33:41.262793216Z", "durationInNanos": 83726080, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_pay_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "83033b37b8934e4d"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "83033b37b8934e4d", "traceState": "", "parentSpanId": "74ac44c4e08e204b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.646461440Z", "endTime": "2021-04-20T20:33:41.647615744Z", "durationInNanos": 1154304, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "6b60bf20aca25776"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "6b60bf20aca25776", "traceState": "", "parentSpanId": "7b17041367225c99", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.623079680Z", "endTime": "2021-04-20T20:33:41.659422720Z", "durationInNanos": 36343040, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b88a8903d68855ac"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "b88a8903d68855ac", "traceState": "", "parentSpanId": "7b17041367225c99", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.662379264Z", "endTime": "2021-04-20T20:33:41.667096576Z", "durationInNanos": 4717312, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7b17041367225c99"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "7b17041367225c99", "traceState": "", "parentSpanId": "1abf21fef72f18ff", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.622877440Z", "endTime": "2021-04-20T20:33:41.669995776Z", "durationInNanos": 47118336, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1e0ea651a120db7b"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "1e0ea651a120db7b", "traceState": "", "parentSpanId": "46c91104e47a2a43", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.501964032Z", "endTime": "2021-04-20T20:33:42.533108224Z", "durationInNanos": 31144192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58598, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "46c91104e47a2a43"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "46c91104e47a2a43", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.499654144Z", "endTime": "2021-04-20T20:33:42.538212352Z", "durationInNanos": 38558208, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b1622ef608acbe07"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "b1622ef608acbe07", "traceState": "", "parentSpanId": "0c5d67b81c5daaa1", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.564037120Z", "endTime": "2021-04-20T20:33:42.564826880Z", "durationInNanos": 789760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "48ab22a6aa9ead3d"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "48ab22a6aa9ead3d", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.581447424Z", "endTime": "2021-04-20T20:33:42.620536064Z", "durationInNanos": 39088640, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "0791aa225a461844"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "0791aa225a461844", "traceState": "", "parentSpanId": "dd10a56f977e819c", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.499253760Z", "endTime": "2021-04-20T20:33:42.631327232Z", "durationInNanos": 132073472, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "dd10a56f977e819c"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "dd10a56f977e819c", "traceState": "", "parentSpanId": "868f60191f3524c9", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.498470144Z", "endTime": "2021-04-20T20:33:42.633447680Z", "durationInNanos": 134977536, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48350, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "3121ff83a994e9da"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "3121ff83a994e9da", "traceState": "", "parentSpanId": "007459ff1ddd5dfb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.640867584Z", "endTime": "2021-04-20T20:33:42.645658112Z", "durationInNanos": 4790528, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "007459ff1ddd5dfb"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "007459ff1ddd5dfb", "traceState": "", "parentSpanId": "4eaffcf10b0ddc1b", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.495881472Z", "endTime": "2021-04-20T20:33:42.649110784Z", "durationInNanos": 153229312, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "11538c0100bd4160"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "11538c0100bd4160", "traceState": "", "parentSpanId": "a0bed7d434593b60", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.451381504Z", "endTime": "2021-04-20T20:33:43.455993600Z", "durationInNanos": 4612096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a0bed7d434593b60"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "a0bed7d434593b60", "traceState": "", "parentSpanId": "36695d818f9b4e9a", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.388621312Z", "endTime": "2021-04-20T20:33:43.458705664Z", "durationInNanos": 70084352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "5268497625ace4e0"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "5268497625ace4e0", "traceState": "", "parentSpanId": "5e7bc4f9aae01a8f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.385700864Z", "endTime": "2021-04-20T20:33:43.466258432Z", "durationInNanos": 80557568, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e272f67b8738c361"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "e272f67b8738c361", "traceState": "", "parentSpanId": "f9e3a2177bd81a72", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.825311744Z", "endTime": "2021-04-20T20:33:43.878611712Z", "durationInNanos": 53299968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58628, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c173a5ab72d12cca"}}
-{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "c173a5ab72d12cca", "traceState": "", "parentSpanId": "4dc028a0167c3cf2", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.664562550Z", "endTime": "2021-04-20T20:33:41.665701036Z", "durationInNanos": 1138486, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "1d6646d320f46f92"}}
-{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "1d6646d320f46f92", "traceState": "", "parentSpanId": "7d14b353b41504e2", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.888482916Z", "endTime": "2021-04-20T20:33:43.889715232Z", "durationInNanos": 1232316, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "cf2a67c23dc23bab"}}
-{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "cf2a67c23dc23bab", "traceState": "", "parentSpanId": "652bc8d3182b25df", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.791001724Z", "endTime": "2021-04-20T20:33:39.792709638Z", "durationInNanos": 1707914, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57778, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "f405f62e61d4181f"}}
-{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "f405f62e61d4181f", "traceState": "", "parentSpanId": "3121ff83a994e9da", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.643002265Z", "endTime": "2021-04-20T20:33:42.644751821Z", "durationInNanos": 1749556, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57852, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "87af24ccbde5bc6b"}}
-{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "87af24ccbde5bc6b", "traceState": "", "parentSpanId": "11538c0100bd4160", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.453001888Z", "endTime": "2021-04-20T20:33:43.454676059Z", "durationInNanos": 1674171, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57862, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "4a2d7a09233223ec"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "4a2d7a09233223ec", "traceState": "", "parentSpanId": "570073e77e68be9d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.206169856Z", "endTime": "2021-04-20T20:33:44.206994688Z", "durationInNanos": 824832, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "c1ae726e0fb621b3"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "c1ae726e0fb621b3", "traceState": "", "parentSpanId": "24d81987a47f33dc", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.252928256Z", "endTime": "2021-04-20T20:33:44.253720576Z", "durationInNanos": 792320, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "d87a0a46511625fb"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "d87a0a46511625fb", "traceState": "", "parentSpanId": "7696d367503845f7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.232229376Z", "endTime": "2021-04-20T20:33:44.266917888Z", "durationInNanos": 34688512, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58642, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7696d367503845f7"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "7696d367503845f7", "traceState": "", "parentSpanId": "885e54cf2034b9f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.229940992Z", "endTime": "2021-04-20T20:33:44.272091648Z", "durationInNanos": 42150656, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "01b449260ce334f8"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "01b449260ce334f8", "traceState": "", "parentSpanId": "885e54cf2034b9f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.320410368Z", "endTime": "2021-04-20T20:33:44.324994048Z", "durationInNanos": 4583680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c85e5dec4106a06a"}}
-{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "c85e5dec4106a06a", "traceState": "", "parentSpanId": "0b957c5bc548b795", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.178796544Z", "endTime": "2021-04-20T20:33:44.335090176Z", "durationInNanos": 156293632, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "bd67ffd1aca8ebd9"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "bd67ffd1aca8ebd9", "traceState": "", "parentSpanId": "0ee38170cee8fb5c", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.555993344Z", "endTime": "2021-04-20T20:33:44.591705344Z", "durationInNanos": 35712000, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "0ee38170cee8fb5c"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "0ee38170cee8fb5c", "traceState": "", "parentSpanId": "afcb84a35556aad5", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.555788544Z", "endTime": "2021-04-20T20:33:44.602074368Z", "durationInNanos": 46285824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "afcb84a35556aad5"}}
-{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "afcb84a35556aad5", "traceState": "", "parentSpanId": "e53a0ddf08ca7fe4", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.554990592Z", "endTime": "2021-04-20T20:33:44.604317184Z", "durationInNanos": 49326592, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32802, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "2131bd5f7b2bb426"}}
-{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "2131bd5f7b2bb426", "traceState": "", "parentSpanId": "d6ed9d2f16247916", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.940555776Z", "endTime": "2021-04-20T20:33:45.019118848Z", "durationInNanos": 78563072, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/pay_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "83e66a83f1a293d1"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "83e66a83f1a293d1", "traceState": "", "parentSpanId": "5205b0912292faea", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.263542528Z", "endTime": "2021-04-20T20:33:45.287819520Z", "durationInNanos": 24276992, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "61e11870abc59f27"}}
-{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "61e11870abc59f27", "traceState": "", "parentSpanId": "3cf94093fb7bea7c", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.260458752Z", "endTime": "2021-04-20T20:33:45.295847168Z", "durationInNanos": 35388416, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "80e3c195c1e1eb31"}}
-{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "80e3c195c1e1eb31", "traceState": "", "parentSpanId": "9e64d04e62cd7e86", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.693580544Z", "endTime": "2021-04-20T20:33:45.694361344Z", "durationInNanos": 780800, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "3f748306070acb27"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "3f748306070acb27", "traceState": "", "parentSpanId": "69af53e3494bca1c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.937683456Z", "endTime": "2021-04-20T20:33:45.938361344Z", "durationInNanos": 677888, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "3a025025e0a3b1fa"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "3a025025e0a3b1fa", "traceState": "", "parentSpanId": "093bfc1b96f299dd", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.912724480Z", "endTime": "2021-04-20T20:33:45.971964416Z", "durationInNanos": 59239936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58706, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "093bfc1b96f299dd"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "093bfc1b96f299dd", "traceState": "", "parentSpanId": "b5ad0d70c2c4c7d6", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.910498560Z", "endTime": "2021-04-20T20:33:45.977039104Z", "durationInNanos": 66540544, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b5ad0d70c2c4c7d6"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "b5ad0d70c2c4c7d6", "traceState": "", "parentSpanId": "04f5292ec03f47ff", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.910301952Z", "endTime": "2021-04-20T20:33:45.987429632Z", "durationInNanos": 77127680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "1abb073eb56f2eea"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "1abb073eb56f2eea", "traceState": "", "parentSpanId": "b2c126fb125a3ec0", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.155314688Z", "endTime": "2021-04-20T20:33:46.180148224Z", "durationInNanos": 24833536, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:46.180106752Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "140b1c6e07ac7569"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "140b1c6e07ac7569", "traceState": "", "parentSpanId": "5edd047783ce31e6", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.197120Z", "endTime": "2021-04-20T20:33:46.223479808Z", "durationInNanos": 26359808, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:46.223439872Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "c220b54c4e5447d7"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "c220b54c4e5447d7", "traceState": "", "parentSpanId": "33c6e729ae31cf8e", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.147583744Z", "endTime": "2021-04-20T20:33:46.289920512Z", "durationInNanos": 142336768, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59968, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "33c6e729ae31cf8e"}}
-{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "33c6e729ae31cf8e", "traceState": "", "parentSpanId": "86582d579095a4b2", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.145408256Z", "endTime": "2021-04-20T20:33:46.294403840Z", "durationInNanos": 148995584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "cfd7fff669823fd7"}}
-{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "cfd7fff669823fd7", "traceState": "", "parentSpanId": "e270a32c23bb3d64", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.524823808Z", "endTime": "2021-04-20T20:33:46.526560Z", "durationInNanos": 1736192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "3b2b065511029f95"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "3b2b065511029f95", "traceState": "", "parentSpanId": "759ba13f98ab3fc6", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.847089408Z", "endTime": "2021-04-20T20:33:46.871549696Z", "durationInNanos": 24460288, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "3f5318f871490765"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "3f5318f871490765", "traceState": "", "parentSpanId": "b2e9f99896086ca7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.795104512Z", "endTime": "2021-04-20T20:33:46.936029952Z", "durationInNanos": 140925440, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "b2e9f99896086ca7"}}
-{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "b2e9f99896086ca7", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.794855168Z", "endTime": "2021-04-20T20:33:46.938890240Z", "durationInNanos": 144035072, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ad657e844f30d14a"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "ad657e844f30d14a", "traceState": "", "parentSpanId": "e0e2f20d2c1b7308", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.212077312Z", "endTime": "2021-04-20T20:33:47.212736768Z", "durationInNanos": 659456, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "8d4b7a48cb7ee8e9"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "8d4b7a48cb7ee8e9", "traceState": "", "parentSpanId": "f78dbd14cda8862e", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.231710720Z", "endTime": "2021-04-20T20:33:47.269911552Z", "durationInNanos": 38200832, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:47.269875456Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "6b10877e5ed07c99"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "6b10877e5ed07c99", "traceState": "", "parentSpanId": "c321930cea7a01b8", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.305689344Z", "endTime": "2021-04-20T20:33:47.306357248Z", "durationInNanos": 667904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "c36ca0e19d93a20e"}}
-{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "c36ca0e19d93a20e", "traceState": "", "parentSpanId": "1e21d6eba3353211", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.185514752Z", "endTime": "2021-04-20T20:33:47.329954560Z", "durationInNanos": 144439808, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "385cdc02dfbd5f9c"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "385cdc02dfbd5f9c", "traceState": "", "parentSpanId": "b7db1195f7777f37", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.813824Z", "endTime": "2021-04-20T20:33:47.849940480Z", "durationInNanos": 36116480, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "728745836581a137"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "728745836581a137", "traceState": "", "parentSpanId": "f4fb15e340c39da3", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.096090880Z", "endTime": "2021-04-20T20:33:48.120184832Z", "durationInNanos": 24093952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "30bde1e6725bc066"}}
-{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "30bde1e6725bc066", "traceState": "", "parentSpanId": "2a4047a9b194cba8", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.387603456Z", "endTime": "2021-04-20T20:33:48.463539712Z", "durationInNanos": 75936256, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32960, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f0839669f041b029"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "f0839669f041b029", "traceState": "", "parentSpanId": "8b858870f3946a12", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.727124224Z", "endTime": "2021-04-20T20:33:48.776144128Z", "durationInNanos": 49019904, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32970, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "8b858870f3946a12"}}
-{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "8b858870f3946a12", "traceState": "", "parentSpanId": "5d15d016d2efc520", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.725030144Z", "endTime": "2021-04-20T20:33:48.780702464Z", "durationInNanos": 55672320, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7ff60cf452880953"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "7ff60cf452880953", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.000432896Z", "endTime": "2021-04-20T20:33:49.036928768Z", "durationInNanos": 36495872, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "17ba287b7e0a55a5"}}
-{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "17ba287b7e0a55a5", "traceState": "", "parentSpanId": "11f0fc7fd6fc8ef7", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.133449435Z", "endTime": "2021-04-20T20:33:48.134655277Z", "durationInNanos": 1205842, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "75432a4e251c77c6"}}
-{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "75432a4e251c77c6", "traceState": "", "parentSpanId": "3922ee10e2a02211", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.982001755Z", "endTime": "2021-04-20T20:33:45.983769151Z", "durationInNanos": 1767396, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57950, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "934a3522bd05ed13"}}
-{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "934a3522bd05ed13", "traceState": "", "parentSpanId": "ad97f94c920dd63a", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.484001785Z", "endTime": "2021-04-20T20:33:47.485831317Z", "durationInNanos": 1829532, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58022, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "ee28b3abcaca75b1"}}
-{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "ee28b3abcaca75b1", "traceState": "", "parentSpanId": "4eeed8358a7d5d30", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.894001979Z", "endTime": "2021-04-20T20:33:47.895816736Z", "durationInNanos": 1814757, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58040, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "362c0d7748107d8f"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "362c0d7748107d8f", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.080640768Z", "endTime": "2021-04-20T20:33:49.120250368Z", "durationInNanos": 39609600, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "6de234553c12cdd0"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "6de234553c12cdd0", "traceState": "", "parentSpanId": "7559e66e65139dc8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.997068544Z", "endTime": "2021-04-20T20:33:49.137304320Z", "durationInNanos": 140235776, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7559e66e65139dc8"}}
-{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "7559e66e65139dc8", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.996784896Z", "endTime": "2021-04-20T20:33:49.140167168Z", "durationInNanos": 143382272, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "fd57eface760a3c2"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "fd57eface760a3c2", "traceState": "", "parentSpanId": "c4eb12c87b56bbaf", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.547070976Z", "endTime": "2021-04-20T20:33:49.547717376Z", "durationInNanos": 646400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "797a61c1556157d8"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "797a61c1556157d8", "traceState": "", "parentSpanId": "5e65bb1294c655ad", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.586952448Z", "endTime": "2021-04-20T20:33:49.587582464Z", "durationInNanos": 630016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "5e65bb1294c655ad"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "5e65bb1294c655ad", "traceState": "", "parentSpanId": "4111fb00ec1efd77", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.567184128Z", "endTime": "2021-04-20T20:33:49.591741696Z", "durationInNanos": 24557568, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:49.591707904Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "4111fb00ec1efd77"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "4111fb00ec1efd77", "traceState": "", "parentSpanId": "977b8ddb69c6d9a7", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.566329344Z", "endTime": "2021-04-20T20:33:49.596302592Z", "durationInNanos": 29973248, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58870, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "977b8ddb69c6d9a7"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "977b8ddb69c6d9a7", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.564026112Z", "endTime": "2021-04-20T20:33:49.601558016Z", "durationInNanos": 37531904, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "704f4cab0d9b5606"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "704f4cab0d9b5606", "traceState": "", "parentSpanId": "bd73a71f8d9cc289", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.627682304Z", "endTime": "2021-04-20T20:33:49.628331008Z", "durationInNanos": 648704, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "28991f1d3a174ce4"}}
-{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "28991f1d3a174ce4", "traceState": "", "parentSpanId": "d0f5f8f6a9167a1c", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.523589632Z", "endTime": "2021-04-20T20:33:49.645100288Z", "durationInNanos": 121510656, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "79a8b5b769a8af40"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "79a8b5b769a8af40", "traceState": "", "parentSpanId": "cc39a5b2d98e4127", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.876797696Z", "endTime": "2021-04-20T20:33:49.896148736Z", "durationInNanos": 19351040, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "cc39a5b2d98e4127"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "cc39a5b2d98e4127", "traceState": "", "parentSpanId": "2c3fe2ecd7602e0b", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.851799296Z", "endTime": "2021-04-20T20:33:49.899272448Z", "durationInNanos": 47473152, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "de9f1128bf12b7b9"}}
-{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "de9f1128bf12b7b9", "traceState": "", "parentSpanId": "1861602b0fed74c0", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.848355584Z", "endTime": "2021-04-20T20:33:49.917926400Z", "durationInNanos": 69570816, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "0d15e0e38cc75348"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "0d15e0e38cc75348", "traceState": "", "parentSpanId": "0b9642ed51dc4523", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.183780864Z", "endTime": "2021-04-20T20:33:50.208142848Z", "durationInNanos": 24361984, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "3b639def2d6ec40f"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "3b639def2d6ec40f", "traceState": "", "parentSpanId": "f53b324dd57c0a67", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.140426496Z", "endTime": "2021-04-20T20:33:50.269464320Z", "durationInNanos": 129037824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33036, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f53b324dd57c0a67"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "f53b324dd57c0a67", "traceState": "", "parentSpanId": "0721e6662945f8c1", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.138248960Z", "endTime": "2021-04-20T20:33:50.274230272Z", "durationInNanos": 135981312, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "0721e6662945f8c1"}}
-{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "0721e6662945f8c1", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.137996544Z", "endTime": "2021-04-20T20:33:50.276978688Z", "durationInNanos": 138982144, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "3a565f7129913c17"}}
-{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "3a565f7129913c17", "traceState": "", "parentSpanId": "59ff85f342e07d43", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.475230464Z", "endTime": "2021-04-20T20:33:50.531948288Z", "durationInNanos": 56717824, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "76d4028a33aa32d4"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "76d4028a33aa32d4", "traceState": "", "parentSpanId": "c80dc4c948d060d2", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.730701312Z", "endTime": "2021-04-20T20:33:50.759436800Z", "durationInNanos": 28735488, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58922, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "7e0f8516534902ba"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "7e0f8516534902ba", "traceState": "", "parentSpanId": "815628d64969d668", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.727141632Z", "endTime": "2021-04-20T20:33:50.855739904Z", "durationInNanos": 128598272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "815628d64969d668"}}
-{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "815628d64969d668", "traceState": "", "parentSpanId": "f16d32410e946012", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.725899008Z", "endTime": "2021-04-20T20:33:50.857993472Z", "durationInNanos": 132094464, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33066, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "06838c62d1f8fc52"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "06838c62d1f8fc52", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.133010176Z", "endTime": "2021-04-20T20:33:51.191095040Z", "durationInNanos": 58084864, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "c2c0543fe0270e38"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "c2c0543fe0270e38", "traceState": "", "parentSpanId": "eb593b21c00b38c7", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.416972800Z", "endTime": "2021-04-20T20:33:51.463561472Z", "durationInNanos": 46588672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "d9dd1b7eed5760a0"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "d9dd1b7eed5760a0", "traceState": "", "parentSpanId": "2b7af871bd8cd43f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.413930240Z", "endTime": "2021-04-20T20:33:51.472114688Z", "durationInNanos": 58184448, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "3301dd384d83dc66"}}
-{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "3301dd384d83dc66", "traceState": "", "parentSpanId": "9de35fba7cb7c4a3", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.679142400Z", "endTime": "2021-04-20T20:33:51.729883904Z", "durationInNanos": 50741504, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33104, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "c5e70373eb296aff"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "c5e70373eb296aff", "traceState": "", "parentSpanId": "49bf3ba4725523ca", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.977397248Z", "endTime": "2021-04-20T20:33:51.978067200Z", "durationInNanos": 669952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "91b0beabefca51d0"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "91b0beabefca51d0", "traceState": "", "parentSpanId": "a7accb6ac082369d", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.956622336Z", "endTime": "2021-04-20T20:33:51.985689344Z", "durationInNanos": 29067008, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58970, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "a7accb6ac082369d"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "a7accb6ac082369d", "traceState": "", "parentSpanId": "6576e80159aee6b8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.954316288Z", "endTime": "2021-04-20T20:33:51.990446336Z", "durationInNanos": 36130048, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "439eff3f753e8e67"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "439eff3f753e8e67", "traceState": "", "parentSpanId": "6576e80159aee6b8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.993564672Z", "endTime": "2021-04-20T20:33:52.029644544Z", "durationInNanos": 36079872, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "e0f5b0c6a6b1bbc2"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "e0f5b0c6a6b1bbc2", "traceState": "", "parentSpanId": "7b8507bd4a5a909f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.055813888Z", "endTime": "2021-04-20T20:33:52.056485632Z", "durationInNanos": 671744, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "ab4ac8bcf7351137"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "ab4ac8bcf7351137", "traceState": "", "parentSpanId": "1717b0bbc49c8b5c", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.034881024Z", "endTime": "2021-04-20T20:33:52.063697664Z", "durationInNanos": 28816640, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58978, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "0124ac48730385cc"}}
-{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "0124ac48730385cc", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.950673408Z", "endTime": "2021-04-20T20:33:52.088491264Z", "durationInNanos": 137817856, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "e978fe4781c7212b"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "e978fe4781c7212b", "traceState": "", "parentSpanId": "f8aedbcbab807a78", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.270512128Z", "endTime": "2021-04-20T20:33:52.275296512Z", "durationInNanos": 4784384, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "0db04213ba31cb79"}}
-{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "0db04213ba31cb79", "traceState": "", "parentSpanId": "66dd3959b912162c", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.205003776Z", "endTime": "2021-04-20T20:33:52.284966144Z", "durationInNanos": 79962368, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f14b6b57d7079a58"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "f14b6b57d7079a58", "traceState": "", "parentSpanId": "9e4947190e28b8f7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.520363008Z", "endTime": "2021-04-20T20:33:52.521067776Z", "durationInNanos": 704768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "2c37405ee8325196"}}
-{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "2c37405ee8325196", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.535895296Z", "endTime": "2021-04-20T20:33:52.571971584Z", "durationInNanos": 36076288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "14148032cdebd6e5"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "14148032cdebd6e5", "traceState": "", "parentSpanId": "d985b5239c10d8bf", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.678805504Z", "endTime": "2021-04-20T20:33:52.703546112Z", "durationInNanos": 24740608, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "ec48acd974e4f4ef"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "ec48acd974e4f4ef", "traceState": "", "parentSpanId": "8873f17b55cf568a", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.717049088Z", "endTime": "2021-04-20T20:33:52.745951744Z", "durationInNanos": 28902656, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59020, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "d85ef60c6b05ea1e"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "d85ef60c6b05ea1e", "traceState": "", "parentSpanId": "e0514a47c90c0ead", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.675259392Z", "endTime": "2021-04-20T20:33:52.823244288Z", "durationInNanos": 147984896, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "a9ae73162186cc7f"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "a9ae73162186cc7f", "traceState": "", "parentSpanId": "ff285f4458209cf3", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.927145216Z", "endTime": "2021-04-20T20:33:52.990285312Z", "durationInNanos": 63140096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "477408f3368f28af"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "477408f3368f28af", "traceState": "", "parentSpanId": "ff285f4458209cf3", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.993329920Z", "endTime": "2021-04-20T20:33:52.997798144Z", "durationInNanos": 4468224, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "f45a94f980605697"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "f45a94f980605697", "traceState": "", "parentSpanId": "470ef7b1b1e8c06c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.238649856Z", "endTime": "2021-04-20T20:33:53.239367680Z", "durationInNanos": 717824, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "c07900555826d95f"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "c07900555826d95f", "traceState": "", "parentSpanId": "68f6536a0523f7f3", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.217669120Z", "endTime": "2021-04-20T20:33:53.248192768Z", "durationInNanos": 30523648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59046, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
-{ "index":{"_id": "854e04d060d378a8"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "854e04d060d378a8", "traceState": "", "parentSpanId": "a4030e9ad85b2a92", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.279769344Z", "endTime": "2021-04-20T20:33:53.280431360Z", "durationInNanos": 662016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "2badcc8448bd5c5b"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "2badcc8448bd5c5b", "traceState": "", "parentSpanId": "6dcb9bfdeb68bef1", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.214871808Z", "endTime": "2021-04-20T20:33:53.338653184Z", "durationInNanos": 123781376, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "79e7e8f4a6b9cfd6"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "79e7e8f4a6b9cfd6", "traceState": "", "parentSpanId": "b52867ccd766e67b", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.210643200Z", "endTime": "2021-04-20T20:33:53.350407680Z", "durationInNanos": 139764480, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60296, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "b52867ccd766e67b"}}
-{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "b52867ccd766e67b", "traceState": "", "parentSpanId": "4c7ff265c1e0c9dc", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.208381952Z", "endTime": "2021-04-20T20:33:53.354845184Z", "durationInNanos": 146463232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
-{ "index":{"_id": "7745e3605083e150"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "7745e3605083e150", "traceState": "", "parentSpanId": "f6b9b0130d0a7765", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.454045184Z", "endTime": "2021-04-20T20:33:53.455569152Z", "durationInNanos": 1523968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
-{ "index":{"_id": "cefea796ccf54813"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "cefea796ccf54813", "traceState": "", "parentSpanId": "28b54e1dd64fcf7d", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.429565696Z", "endTime": "2021-04-20T20:33:53.503151872Z", "durationInNanos": 73586176, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
-{ "index":{"_id": "28b54e1dd64fcf7d"}}
-{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "28b54e1dd64fcf7d", "traceState": "", "parentSpanId": "1dc7b46c2357c388", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.428727808Z", "endTime": "2021-04-20T20:33:53.505276160Z", "durationInNanos": 76548352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33208, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
-{ "index":{"_id": "fc1d1ffce95a27aa"}}
-{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "fc1d1ffce95a27aa", "traceState": "", "parentSpanId": "0f929cd09feb717a", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.818457432Z", "endTime": "2021-04-20T20:33:52.819488855Z", "durationInNanos": 1031423, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "f44426165fbba4d0"}}
-{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "f44426165fbba4d0", "traceState": "", "parentSpanId": "b272143e732a91e9", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.995465166Z", "endTime": "2021-04-20T20:33:52.996460896Z", "durationInNanos": 995730, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
-{ "index":{"_id": "9fd37843dd616fab"}}
-{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "9fd37843dd616fab", "traceState": "", "parentSpanId": "3ed06551056e1fa6", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.176001692Z", "endTime": "2021-04-20T20:33:51.177560735Z", "durationInNanos": 1559043, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58184, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
-{ "index":{"_id": "fce44d7569908ba7"}}
-{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "fce44d7569908ba7", "traceState": "", "parentSpanId": "608bd5e547e88e3e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.477002352Z", "endTime": "2021-04-20T20:33:51.478943130Z", "durationInNanos": 1940778, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58194, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
diff --git a/dashboards-observability/.cypress/utils/otel-v1-apm-span-000002.json b/dashboards-observability/.cypress/utils/otel-v1-apm-span-000002.json
new file mode 100644
index 000000000..9166e0e68
--- /dev/null
+++ b/dashboards-observability/.cypress/utils/otel-v1-apm-span-000002.json
@@ -0,0 +1,968 @@
+{"index":{"_id":"ba677184b5efee9c"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"ba677184b5efee9c","traceState":"","parentSpanId":"05d70136fe1f5159","name":"/logs","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:23:59.461002874Z","endTime":"2021-03-25T17:23:59.463725749Z","durationInNanos":2722875,"serviceName":"analytics-service","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.net@peer@ip":"127.0.0.1","span.attributes.http@url":"http://localhost:8087/logs","span.attributes.thread@name":"http-nio-8087-exec-8","instrumentationLibrary.version":"0.10.1","resource.attributes.telemetry@sdk@language":"java","span.attributes.thread@id":135,"resource.attributes.telemetry@sdk@version":"0.10.0","resource.attributes.service@name":"analytics-service","status.code":0,"instrumentationLibrary.name":"io.opentelemetry.auto.servlet","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.25.1","span.attributes.net@peer@port":56692,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@auto@version":"0.10.1","span.attributes.http@flavor":"HTTP/1.1","span.attributes.http@status_code":200,"span.attributes.http@client_ip":"127.0.0.1"}
+{"index":{"_id":"3ed514d3a35fcf2f"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"3ed514d3a35fcf2f","traceState":"","parentSpanId":"c8fff65b158a58b0","name":"cart_sold","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.328946176Z","endTime":"2021-03-25T17:23:59.396863488Z","durationInNanos":67917312,"serviceName":"database","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@sdk@language":"python","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140307275923408","resource.attributes.service@name":"database","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","status.code":0,"instrumentationLibrary.name":"__main__"}
+{"index":{"_id":"a1464485edf9588e"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"a1464485edf9588e","traceState":"","parentSpanId":"3ed514d3a35fcf2f","name":"mysql.APM","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.351120384Z","endTime":"2021-03-25T17:23:59.381280256Z","durationInNanos":30159872,"serviceName":"database","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.db@user":"root","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.net@peer@name":"localhost","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140307275923408","resource.attributes.service@name":"database","span.attributes.component":"mysql","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.mysql","span.attributes.db@type":"sql","span.attributes.net@peer@port":3306,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.db@instance":"APM","span.attributes.db@statement":"TRUNCATE TABLE User_Carts","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal"}
+{"index":{"_id":"05d70136fe1f5159"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"05d70136fe1f5159","traceState":"","parentSpanId":"e2ab54f8e8a03c99","name":"HTTP POST","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.447067904Z","endTime":"2021-03-25T17:23:59.466000896Z","durationInNanos":18932992,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.http@url":"http://localhost:8087/logs","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.http@status_text":"","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.requests","span.attributes.http@method":"POST","resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@status_code":200}
+{"index":{"_id":"e2ab54f8e8a03c99"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"e2ab54f8e8a03c99","traceState":"","parentSpanId":"f9d9427c810291d8","name":"pay_order","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.324906496Z","endTime":"2021-03-25T17:23:59.473705472Z","durationInNanos":148798976,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.telemetry@sdk@language":"python","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","status.code":0,"instrumentationLibrary.name":"__main__"}
+{"index":{"_id":"7df5609a6d104736"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"7df5609a6d104736","traceState":"","parentSpanId":"542385797ac7122c","name":"HTTP POST","kind":"SPAN_KIND_CLIENT","startTime":"2021-03-25T17:23:59.321473280Z","endTime":"2021-03-25T17:23:59.490911488Z","durationInNanos":169438208,"serviceName":"frontend-client","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.http@url":"http://localhost:8088/pay_order","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.http@status_text":"OK","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@name":"frontend-client","span.attributes.component":"http","status.code":0,"instrumentationLibrary.name":"opentelemetry.instrumentation.requests","span.attributes.http@method":"POST","resource.attributes.telemetry@sdk@name":"opentelemetry","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@status_code":200}
+{"index":{"_id":"05ef9498724dc42f"}}
+{"traceId":"690d3c7af1a78cf89c43ef4b07c05b43","spanId":"05ef9498724dc42f","traceState":"","parentSpanId":"ba677184b5efee9c","name":"LoggingController.save","kind":"SPAN_KIND_INTERNAL","startTime":"2021-03-25T17:23:59.461838595Z","endTime":"2021-03-25T17:23:59.463482824Z","durationInNanos":1644229,"serviceName":"analytics-service","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"client_pay_order","traceGroupFields.endTime":"2021-03-25T17:23:59.497588224Z","traceGroupFields.statusCode":0,"traceGroupFields.durationInNanos":176424960,"span.attributes.thread@name":"http-nio-8087-exec-8","resource.attributes.telemetry@sdk@name":"opentelemetry","instrumentationLibrary.version":"0.10.1","resource.attributes.telemetry@sdk@language":"java","span.attributes.thread@id":135,"resource.attributes.telemetry@auto@version":"0.10.1","resource.attributes.telemetry@sdk@version":"0.10.0","resource.attributes.service@name":"analytics-service","status.code":0,"instrumentationLibrary.name":"io.opentelemetry.auto.spring-webmvc"}
+{"index":{"_id":"eea507e2c1767a48"}}
+{"traceId":"24112fdc5dfb6886638e64458220b1c8","spanId":"eea507e2c1767a48","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:42:17.381757696Z","endTime":"2021-03-25T17:42:17.383773440Z","durationInNanos":2015744,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:42:17.383773440Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":2015744,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":37610,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
+{"index":{"_id":"a32571a7f379563e"}}
+{"traceId":"f9389809a15b165300bf99ca10c1d094","spanId":"a32571a7f379563e","traceState":"","parentSpanId":"","name":"HTTP GET","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:42:42.526520320Z","endTime":"2021-03-25T17:42:42.527678720Z","durationInNanos":1158400,"serviceName":"recommendation","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP GET","traceGroupFields.endTime":"2021-03-25T17:42:42.527678720Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1158400,"span.attributes.net@peer@ip":"139.162.75.102","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8086,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"140465266593744","resource.attributes.service@name":"recommendation","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"GET","span.attributes.http@user_agent":"HTTP Banner Detection (https://security.ipip.net)","span.attributes.net@peer@port":43096,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8086","span.attributes.http@target":"/","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
+{"index":{"_id":"fc11194d7d60a403"}}
+{"traceId":"5c8f22e7dce504a5b7610590d5426b16","spanId":"fc11194d7d60a403","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:25:41.732983296Z","endTime":"2021-03-25T17:25:41.734188544Z","durationInNanos":1205248,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:25:41.734188544Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1205248,"span.attributes.net@peer@ip":"128.199.87.139","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.12.4","span.attributes.net@peer@port":59096,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
+{"index":{"_id":"8f0e5fd10849cc70"}}
+{"traceId":"f151842ced0cd956ec005da199424336","spanId":"8f0e5fd10849cc70","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:48:05.517435904Z","endTime":"2021-03-25T17:48:05.518697728Z","durationInNanos":1261824,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:48:05.518697728Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1261824,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":59430,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
+{"index":{"_id":"244bc4ca978dd618"}}
+{"traceId":"be0a3dceda2ecf601fd2e476fef3ee07","spanId":"244bc4ca978dd618","traceState":"","parentSpanId":"","name":"HTTP POST","kind":"SPAN_KIND_SERVER","startTime":"2021-03-25T17:55:12.854892800Z","endTime":"2021-03-25T17:55:12.856072192Z","durationInNanos":1179392,"serviceName":"order","events":[],"links":[],"droppedAttributesCount":0,"droppedEventsCount":0,"droppedLinksCount":0,"traceGroup":"HTTP POST","traceGroupFields.endTime":"2021-03-25T17:55:12.856072192Z","traceGroupFields.statusCode":2,"traceGroupFields.durationInNanos":1179392,"span.attributes.net@peer@ip":"165.232.135.114","instrumentationLibrary.version":"0.14b0","resource.attributes.telemetry@sdk@language":"python","span.attributes.host@port":8088,"span.attributes.http@status_text":"NOT FOUND","resource.attributes.telemetry@sdk@version":"0.14b0","resource.attributes.service@instance@id":"139858677314952","resource.attributes.service@name":"order","span.attributes.component":"http","status.code":2,"instrumentationLibrary.name":"opentelemetry.instrumentation.flask","span.attributes.http@method":"POST","span.attributes.http@user_agent":"python-requests/2.6.0 CPython/2.7.5 Linux/3.10.0-1160.15.2.el7.x86_64","span.attributes.net@peer@port":35686,"resource.attributes.telemetry@sdk@name":"opentelemetry","span.attributes.http@server_name":"0.0.0.0","span.attributes.http@host":"54.202.237.120:8088","span.attributes.http@target":"/ws/v1/cluster/apps/new-application","span.attributes.http@scheme":"http","resource.attributes.host@hostname":"ip-172-31-10-8.us-west-2.compute.internal","span.attributes.http@flavor":"1.1","span.attributes.http@status_code":404}
+{ "index":{"_id": "fe945197d943bda9"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "fe945197d943bda9", "traceState": "", "parentSpanId": "2bdbeb0df10ab869", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.022309888Z", "endTime": "2021-04-20T20:33:42.047018752Z", "durationInNanos": 24708864, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "2bdbeb0df10ab869"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "2bdbeb0df10ab869", "traceState": "", "parentSpanId": "7a5994c2d61252d8", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.002375424Z", "endTime": "2021-04-20T20:33:42.050758400Z", "durationInNanos": 48382976, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "bae5c2ac73588d38"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "bae5c2ac73588d38", "traceState": "", "parentSpanId": "d6668b8cd17b28aa", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.999037184Z", "endTime": "2021-04-20T20:33:42.070543360Z", "durationInNanos": 71506176, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "d6668b8cd17b28aa"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "d6668b8cd17b28aa", "traceState": "", "parentSpanId": "2786ea5cfba1d51c", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.998258944Z", "endTime": "2021-04-20T20:33:42.073518592Z", "durationInNanos": 75259648, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60962, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "de34ef4183a4705b"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "de34ef4183a4705b", "traceState": "", "parentSpanId": "1e0ea651a120db7b", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.502849536Z", "endTime": "2021-04-20T20:33:42.529717248Z", "durationInNanos": 26867712, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "cdf9197db50c18a4"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "cdf9197db50c18a4", "traceState": "", "parentSpanId": "baa1e8371ec989bd", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.543471872Z", "endTime": "2021-04-20T20:33:42.573529344Z", "durationInNanos": 30057472, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58602, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "baa1e8371ec989bd"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "baa1e8371ec989bd", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.541210624Z", "endTime": "2021-04-20T20:33:42.578594816Z", "durationInNanos": 37384192, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a545017537d582f9"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "a545017537d582f9", "traceState": "", "parentSpanId": "48ab22a6aa9ead3d", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.583665664Z", "endTime": "2021-04-20T20:33:42.615355392Z", "durationInNanos": 31689728, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58606, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "868f60191f3524c9"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "868f60191f3524c9", "traceState": "", "parentSpanId": "007459ff1ddd5dfb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.496294144Z", "endTime": "2021-04-20T20:33:42.638115584Z", "durationInNanos": 141821440, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "5e7bc4f9aae01a8f"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "5e7bc4f9aae01a8f", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.385450240Z", "endTime": "2021-04-20T20:33:43.469037824Z", "durationInNanos": 83587584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "5d8912365e6688f3"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "5d8912365e6688f3", "traceState": "", "parentSpanId": "e272f67b8738c361", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.826181376Z", "endTime": "2021-04-20T20:33:43.875000320Z", "durationInNanos": 48818944, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7e35eb6c56afcde0"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "7e35eb6c56afcde0", "traceState": "", "parentSpanId": "5b366e385260a8f1", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.822093312Z", "endTime": "2021-04-20T20:33:43.896168448Z", "durationInNanos": 74075136, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32772, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "5b366e385260a8f1"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "5b366e385260a8f1", "traceState": "", "parentSpanId": "c785f8a4fa3c337f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.819960576Z", "endTime": "2021-04-20T20:33:43.900840704Z", "durationInNanos": 80880128, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c785f8a4fa3c337f"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "c785f8a4fa3c337f", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.819711488Z", "endTime": "2021-04-20T20:33:43.903628288Z", "durationInNanos": 83916800, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "959d996c94b64416"}}
+{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "959d996c94b64416", "traceState": "", "parentSpanId": "4ed24722154a0621", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.000507533Z", "endTime": "2021-04-20T20:33:39.001814067Z", "durationInNanos": 1306534, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "b04dd1440b46ea4a"}}
+{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "b04dd1440b46ea4a", "traceState": "", "parentSpanId": "1fbcd1691508fa92", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.859492193Z", "endTime": "2021-04-20T20:33:40.860705473Z", "durationInNanos": 1213280, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "4ed24722154a0621"}}
+{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "4ed24722154a0621", "traceState": "", "parentSpanId": "62acd7c17a0ba6b5", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.000001917Z", "endTime": "2021-04-20T20:33:39.001944606Z", "durationInNanos": 1942689, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57758, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "6dcf6a50115bf9bf"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "6dcf6a50115bf9bf", "traceState": "", "parentSpanId": "7052b8e18f95d355", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.293001852Z", "endTime": "2021-04-20T20:33:40.294769849Z", "durationInNanos": 1767997, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57788, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "a981fd033e3a7491"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "a981fd033e3a7491", "traceState": "", "parentSpanId": "3d3423c981805776", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.248002296Z", "endTime": "2021-04-20T20:33:41.250091967Z", "durationInNanos": 2089671, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57808, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "c2bf96e64de1f749"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "c2bf96e64de1f749", "traceState": "", "parentSpanId": "82f2995c402620bf", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.064002408Z", "endTime": "2021-04-20T20:33:42.066510378Z", "durationInNanos": 2507970, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57830, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "7d14b353b41504e2"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "7d14b353b41504e2", "traceState": "", "parentSpanId": "66305d54c87ada37", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.888001836Z", "endTime": "2021-04-20T20:33:43.889846781Z", "durationInNanos": 1844945, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57872, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "638057deacc19370"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "638057deacc19370", "traceState": "", "parentSpanId": "570073e77e68be9d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.210460160Z", "endTime": "2021-04-20T20:33:44.211786496Z", "durationInNanos": 1326336, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "72fd9aa427e26550"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "72fd9aa427e26550", "traceState": "", "parentSpanId": "63b924688fd8e338", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.184596992Z", "endTime": "2021-04-20T20:33:44.221891840Z", "durationInNanos": 37294848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58638, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "74a72003d10b4891"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "74a72003d10b4891", "traceState": "", "parentSpanId": "9d74d751ce8f5632", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.298237184Z", "endTime": "2021-04-20T20:33:44.299052800Z", "durationInNanos": 815616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "9d74d751ce8f5632"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "9d74d751ce8f5632", "traceState": "", "parentSpanId": "2311bcf70d68331c", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.278095616Z", "endTime": "2021-04-20T20:33:44.309211392Z", "durationInNanos": 31115776, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "d45da7dee8c886ed"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "d45da7dee8c886ed", "traceState": "", "parentSpanId": "8fb23e8fa1ec36c4", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.578994944Z", "endTime": "2021-04-20T20:33:44.579650560Z", "durationInNanos": 655616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "10c91a64a809f0f9"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "10c91a64a809f0f9", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.552633344Z", "endTime": "2021-04-20T20:33:44.611744256Z", "durationInNanos": 59110912, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7359981596903c3f"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "7359981596903c3f", "traceState": "", "parentSpanId": "61aa3d8d2d402633", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.946950400Z", "endTime": "2021-04-20T20:33:44.993092352Z", "durationInNanos": 46141952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "61aa3d8d2d402633"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "61aa3d8d2d402633", "traceState": "", "parentSpanId": "0fcb489ad5418516", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.946038528Z", "endTime": "2021-04-20T20:33:44.996396288Z", "durationInNanos": 50357760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58668, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "6f35a199b046be10"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "6f35a199b046be10", "traceState": "", "parentSpanId": "83e66a83f1a293d1", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.283089152Z", "endTime": "2021-04-20T20:33:45.284170496Z", "durationInNanos": 1081344, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "5205b0912292faea"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "5205b0912292faea", "traceState": "", "parentSpanId": "61e11870abc59f27", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.262661120Z", "endTime": "2021-04-20T20:33:45.291168768Z", "durationInNanos": 28507648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58678, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "3cf94093fb7bea7c"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "3cf94093fb7bea7c", "traceState": "", "parentSpanId": "075721f8c8fe8187", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.260254208Z", "endTime": "2021-04-20T20:33:45.306146816Z", "durationInNanos": 45892608, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "075721f8c8fe8187"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "075721f8c8fe8187", "traceState": "", "parentSpanId": "6164378b120c9a33", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.259456Z", "endTime": "2021-04-20T20:33:45.308376320Z", "durationInNanos": 48920320, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32822, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "fe4076542b41d40b"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "fe4076542b41d40b", "traceState": "", "parentSpanId": "68d63100ba9ee351", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.613371648Z", "endTime": "2021-04-20T20:33:45.614105088Z", "durationInNanos": 733440, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "4cc7f89e7a456e50"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "4cc7f89e7a456e50", "traceState": "", "parentSpanId": "8cf5c6a43ee7642e", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.672583936Z", "endTime": "2021-04-20T20:33:45.701916160Z", "durationInNanos": 29332224, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58696, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "ded3687b9758bf59"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "ded3687b9758bf59", "traceState": "", "parentSpanId": "8ca1e3b61d66dac5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.582414080Z", "endTime": "2021-04-20T20:33:45.724472064Z", "durationInNanos": 142057984, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9a880188bcb44cda"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "9a880188bcb44cda", "traceState": "", "parentSpanId": "22b1d496a103d5d4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.193865472Z", "endTime": "2021-04-20T20:33:46.233754624Z", "durationInNanos": 39889152, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "211e3fa733083be7"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "211e3fa733083be7", "traceState": "", "parentSpanId": "6f7eafee7d68115c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.259891200Z", "endTime": "2021-04-20T20:33:46.260595456Z", "durationInNanos": 704256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "203faf4d95696dc4"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "203faf4d95696dc4", "traceState": "", "parentSpanId": "01e2845682343300", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.239240960Z", "endTime": "2021-04-20T20:33:46.270526720Z", "durationInNanos": 31285760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58726, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "30652f6f8b511470"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "30652f6f8b511470", "traceState": "", "parentSpanId": "6abbf17273b9d804", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.151000320Z", "endTime": "2021-04-20T20:33:46.280569856Z", "durationInNanos": 129569536, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48470, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "6abbf17273b9d804"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "6abbf17273b9d804", "traceState": "", "parentSpanId": "cadc045e30deb39c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.148769024Z", "endTime": "2021-04-20T20:33:46.285116928Z", "durationInNanos": 136347904, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "86582d579095a4b2"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "86582d579095a4b2", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.145158144Z", "endTime": "2021-04-20T20:33:46.297544448Z", "durationInNanos": 152386304, "serviceName": "frontend-client", "events": [ { "time": "2021-04-20T20:33:46.297516032Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "AssertionError", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "/app/client.py", line 179, in checkout assert checkoutAPIRequest.status_code == 200 AssertionError """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "status.message": "AssertionError: ", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "733fc257ce126bd9"}}
+{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "733fc257ce126bd9", "traceState": "", "parentSpanId": "e270a32c23bb3d64", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.530245888Z", "endTime": "2021-04-20T20:33:46.552403200Z", "durationInNanos": 22157312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "d3e652fe39797f07"}}
+{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "d3e652fe39797f07", "traceState": "", "parentSpanId": "e35c1a3d860c70aa", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.501878016Z", "endTime": "2021-04-20T20:33:46.563703296Z", "durationInNanos": 61825280, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "93a311e112248f38"}}
+{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "93a311e112248f38", "traceState": "", "parentSpanId": "7d9e1df2e1915cb1", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.498651904Z", "endTime": "2021-04-20T20:33:46.581459456Z", "durationInNanos": 82807552, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "13738600ae869fe9"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "13738600ae869fe9", "traceState": "", "parentSpanId": "7c37927033d44c5c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.905734912Z", "endTime": "2021-04-20T20:33:46.906381056Z", "durationInNanos": 646144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "7c37927033d44c5c"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "7c37927033d44c5c", "traceState": "", "parentSpanId": "704ecef0adc44ed2", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.885713920Z", "endTime": "2021-04-20T20:33:46.910141696Z", "durationInNanos": 24427776, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "4bac6e5bfd5892b4"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "4bac6e5bfd5892b4", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.921752064Z", "endTime": "2021-04-20T20:33:46.926354688Z", "durationInNanos": 4602624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "ceb7f50ca3f6e4d8"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "ceb7f50ca3f6e4d8", "traceState": "", "parentSpanId": "5f0f95a6e744be7f", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.191190528Z", "endTime": "2021-04-20T20:33:47.221020672Z", "durationInNanos": 29830144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58764, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "5f0f95a6e744be7f"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "5f0f95a6e744be7f", "traceState": "", "parentSpanId": "3e1ca23a1316a089", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.188976640Z", "endTime": "2021-04-20T20:33:47.225834496Z", "durationInNanos": 36857856, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "c321930cea7a01b8"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "c321930cea7a01b8", "traceState": "", "parentSpanId": "45b57a8187c98ac7", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.285538560Z", "endTime": "2021-04-20T20:33:47.310507008Z", "durationInNanos": 24968448, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:47.310474496Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "f707df9bafaf7974"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "f707df9bafaf7974", "traceState": "", "parentSpanId": "1d9787eae41fc84d", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.182018048Z", "endTime": "2021-04-20T20:33:47.339902976Z", "durationInNanos": 157884928, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "1d9787eae41fc84d"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "1d9787eae41fc84d", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.181764352Z", "endTime": "2021-04-20T20:33:47.342982400Z", "durationInNanos": 161218048, "serviceName": "frontend-client", "events": [ { "time": "2021-04-20T20:33:47.342953472Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "AssertionError", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "/app/client.py", line 179, in checkout assert checkoutAPIRequest.status_code == 200 AssertionError """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "status.message": "AssertionError: ", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ad97f94c920dd63a"}}
+{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "ad97f94c920dd63a", "traceState": "", "parentSpanId": "5b03c5aa49169de7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.481642240Z", "endTime": "2021-04-20T20:33:47.486791168Z", "durationInNanos": 5148928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "526236d61de39741"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "526236d61de39741", "traceState": "", "parentSpanId": "556b9dbb760a1f55", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.798135808Z", "endTime": "2021-04-20T20:33:47.798772480Z", "durationInNanos": 636672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "556b9dbb760a1f55"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "556b9dbb760a1f55", "traceState": "", "parentSpanId": "a0333ab0c0fb425e", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.778251008Z", "endTime": "2021-04-20T20:33:47.802673152Z", "durationInNanos": 24422144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "48c5f132edd1dce1"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "48c5f132edd1dce1", "traceState": "", "parentSpanId": "8d13c5fb5cb910ab", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.773860864Z", "endTime": "2021-04-20T20:33:47.903245568Z", "durationInNanos": 129384704, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32932, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f4fb15e340c39da3"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "f4fb15e340c39da3", "traceState": "", "parentSpanId": "36362df397ac500d", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.095176192Z", "endTime": "2021-04-20T20:33:48.123719936Z", "durationInNanos": 28543744, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58806, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9a8427df12be8522"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "9a8427df12be8522", "traceState": "", "parentSpanId": "60b801fae48abf9b", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.091967488Z", "endTime": "2021-04-20T20:33:48.140747776Z", "durationInNanos": 48780288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32950, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a23201e2aa2bf778"}}
+{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "a23201e2aa2bf778", "traceState": "", "parentSpanId": "e2ce196e32791fa8", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.390765568Z", "endTime": "2021-04-20T20:33:48.446376192Z", "durationInNanos": 55610624, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58816, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e2ce196e32791fa8"}}
+{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "e2ce196e32791fa8", "traceState": "", "parentSpanId": "33de151285a224b8", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.388591104Z", "endTime": "2021-04-20T20:33:48.451160064Z", "durationInNanos": 62568960, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "5d15d016d2efc520"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "5d15d016d2efc520", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.724736768Z", "endTime": "2021-04-20T20:33:48.783604992Z", "durationInNanos": 58868224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1ceb1ee0c0c5a3d7"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "1ceb1ee0c0c5a3d7", "traceState": "", "parentSpanId": "81de5d2c6aa0859e", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.042982400Z", "endTime": "2021-04-20T20:33:49.067498752Z", "durationInNanos": 24516352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "8397412a4368c536"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "8397412a4368c536", "traceState": "", "parentSpanId": "b3e2c3a351f4d833", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.322510254Z", "endTime": "2021-04-20T20:33:44.323607252Z", "durationInNanos": 1096998, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "1b7829585cbc0b01"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "1b7829585cbc0b01", "traceState": "", "parentSpanId": "552e8512fb52ccb5", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.596480225Z", "endTime": "2021-04-20T20:33:44.597655556Z", "durationInNanos": 1175331, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "5610211164d655f6"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "5610211164d655f6", "traceState": "", "parentSpanId": "d2025fa5bde68d4c", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.006493344Z", "endTime": "2021-04-20T20:33:45.007802848Z", "durationInNanos": 1309504, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "e8af87596517f6bf"}}
+{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "e8af87596517f6bf", "traceState": "", "parentSpanId": "934a3522bd05ed13", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.484509396Z", "endTime": "2021-04-20T20:33:47.485676993Z", "durationInNanos": 1167597, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "d2025fa5bde68d4c"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "d2025fa5bde68d4c", "traceState": "", "parentSpanId": "5ce9b5237f2b2bbd", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.006001630Z", "endTime": "2021-04-20T20:33:45.007923360Z", "durationInNanos": 1921730, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57912, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "fec494ea1cd015e3"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "fec494ea1cd015e3", "traceState": "", "parentSpanId": "04f07ddda2ec832d", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.301002074Z", "endTime": "2021-04-20T20:33:45.302720699Z", "durationInNanos": 1718625, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57922, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "2ac8b4cda3c0f1f9"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "2ac8b4cda3c0f1f9", "traceState": "", "parentSpanId": "d7ae88514a0b9617", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.711001942Z", "endTime": "2021-04-20T20:33:45.712721718Z", "durationInNanos": 1719776, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57940, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "e4f2d38e4f128be7"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "e4f2d38e4f128be7", "traceState": "", "parentSpanId": "4bac6e5bfd5892b4", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.924001969Z", "endTime": "2021-04-20T20:33:46.925747176Z", "durationInNanos": 1745207, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57996, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "74dbc2be658b50d8"}}
+{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "74dbc2be658b50d8", "traceState": "", "parentSpanId": "d3bce0f9acda8b4e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.456001869Z", "endTime": "2021-04-20T20:33:48.457554150Z", "durationInNanos": 1552281, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58060, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "0c1e1c234af592e4"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "0c1e1c234af592e4", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.039726592Z", "endTime": "2021-04-20T20:33:49.077204224Z", "durationInNanos": 37477632, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c6c238ba3d8255f4"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "c6c238ba3d8255f4", "traceState": "", "parentSpanId": "27d4fe07134ea308", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.000050176Z", "endTime": "2021-04-20T20:33:49.130614784Z", "durationInNanos": 130564608, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "fb628320c3bd92c1"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "fb628320c3bd92c1", "traceState": "", "parentSpanId": "c7c175f4366ce130", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.312768512Z", "endTime": "2021-04-20T20:33:49.313572864Z", "durationInNanos": 804352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "d03fde256c0d5e87"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "d03fde256c0d5e87", "traceState": "", "parentSpanId": "1e3aecf00776002e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.354710528Z", "endTime": "2021-04-20T20:33:49.359258880Z", "durationInNanos": 4548352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "8979ca2f03690516"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "8979ca2f03690516", "traceState": "", "parentSpanId": "f79bee55c88da9dd", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.282687488Z", "endTime": "2021-04-20T20:33:49.369189632Z", "durationInNanos": 86502144, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b5e9c2df83b5c950"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "b5e9c2df83b5c950", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.604470016Z", "endTime": "2021-04-20T20:33:49.642110208Z", "durationInNanos": 37640192, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId apple", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "4167f155e728b1bf"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "4167f155e728b1bf", "traceState": "", "parentSpanId": "bb41f245f32492e4", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.519380224Z", "endTime": "2021-04-20T20:33:49.656816384Z", "durationInNanos": 137436160, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60116, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "5175f8f67d791920"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "5175f8f67d791920", "traceState": "", "parentSpanId": "cc39a5b2d98e4127", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.871913728Z", "endTime": "2021-04-20T20:33:49.873131008Z", "durationInNanos": 1217280, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "ecc02e73350ce790"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "ecc02e73350ce790", "traceState": "", "parentSpanId": "de9f1128bf12b7b9", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.848557312Z", "endTime": "2021-04-20T20:33:49.907510272Z", "durationInNanos": 58952960, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "1861602b0fed74c0"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "1861602b0fed74c0", "traceState": "", "parentSpanId": "a9019c51b85c9ac6", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.847567872Z", "endTime": "2021-04-20T20:33:49.920374784Z", "durationInNanos": 72806912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33026, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a9019c51b85c9ac6"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "a9019c51b85c9ac6", "traceState": "", "parentSpanId": "034ed8cfb8ba682a", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.845530624Z", "endTime": "2021-04-20T20:33:49.925377792Z", "durationInNanos": 79847168, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d6737261234573e3"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "d6737261234573e3", "traceState": "", "parentSpanId": "0fa03fca5ea8c051", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.143993600Z", "endTime": "2021-04-20T20:33:50.172754688Z", "durationInNanos": 28761088, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58892, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e684414d71481506"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "e684414d71481506", "traceState": "", "parentSpanId": "55b6879fed1f14b7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.242910208Z", "endTime": "2021-04-20T20:33:50.243621632Z", "durationInNanos": 711424, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "25d2d59e3e627ee7"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "25d2d59e3e627ee7", "traceState": "", "parentSpanId": "6a539e36635daed1", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.481526016Z", "endTime": "2021-04-20T20:33:50.506380544Z", "durationInNanos": 24854528, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "13bed71d66dcc038"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "13bed71d66dcc038", "traceState": "", "parentSpanId": "9232ae83ea33fee8", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.478371840Z", "endTime": "2021-04-20T20:33:50.514467584Z", "durationInNanos": 36095744, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c29268a1fd31d7d1"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "c29268a1fd31d7d1", "traceState": "", "parentSpanId": "9232ae83ea33fee8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.517328128Z", "endTime": "2021-04-20T20:33:50.522111488Z", "durationInNanos": 4783360, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7ca71ea50061e17a"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "7ca71ea50061e17a", "traceState": "", "parentSpanId": "2e36371a9ffe2dc0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.751403008Z", "endTime": "2021-04-20T20:33:50.752038912Z", "durationInNanos": 635904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "c7c7d4012d81b142"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "c7c7d4012d81b142", "traceState": "", "parentSpanId": "e7287e116f07049d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.792653056Z", "endTime": "2021-04-20T20:33:50.793349632Z", "durationInNanos": 696576, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "ecc0e3f8be5250dd"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "ecc0e3f8be5250dd", "traceState": "", "parentSpanId": "cebaa948cfa4cc19", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.811156480Z", "endTime": "2021-04-20T20:33:50.840189440Z", "durationInNanos": 29032960, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58930, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "534023ef492ea75d"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "534023ef492ea75d", "traceState": "", "parentSpanId": "c5ab512bce3105ef", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.158956032Z", "endTime": "2021-04-20T20:33:51.159533568Z", "durationInNanos": 577536, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "e9893407bba95bf0"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "e9893407bba95bf0", "traceState": "", "parentSpanId": "76dfb45c3ba7873f", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.136340992Z", "endTime": "2021-04-20T20:33:51.171475200Z", "durationInNanos": 35134208, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "608bd5e547e88e3e"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "608bd5e547e88e3e", "traceState": "", "parentSpanId": "2b7af871bd8cd43f", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.475266048Z", "endTime": "2021-04-20T20:33:51.480210688Z", "durationInNanos": 4944640, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "bd638d2bf13e4f41"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "bd638d2bf13e4f41", "traceState": "", "parentSpanId": "8defb053817ab655", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.412930816Z", "endTime": "2021-04-20T20:33:51.485616640Z", "durationInNanos": 72685824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33094, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "dcab66f931f7fc5b"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "dcab66f931f7fc5b", "traceState": "", "parentSpanId": "", "name": "client_pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.410483968Z", "endTime": "2021-04-20T20:33:51.493332480Z", "durationInNanos": 82848512, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_pay_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "9b81a0201a53b84c"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "9b81a0201a53b84c", "traceState": "", "parentSpanId": "de85f1e0d746da28", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.682416128Z", "endTime": "2021-04-20T20:33:51.712218624Z", "durationInNanos": 29802496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58960, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e2a28bb8e6bf64ca"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "e2a28bb8e6bf64ca", "traceState": "", "parentSpanId": "3301dd384d83dc66", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.680000512Z", "endTime": "2021-04-20T20:33:51.727677440Z", "durationInNanos": 47676928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "9de35fba7cb7c4a3"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "9de35fba7cb7c4a3", "traceState": "", "parentSpanId": "637cedb12aa88454", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.677016320Z", "endTime": "2021-04-20T20:33:51.734535680Z", "durationInNanos": 57519360, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "637cedb12aa88454"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "637cedb12aa88454", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.676719872Z", "endTime": "2021-04-20T20:33:51.737385984Z", "durationInNanos": 60666112, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "06f27e83cdad4af6"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "06f27e83cdad4af6", "traceState": "", "parentSpanId": "439eff3f753e8e67", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.995934208Z", "endTime": "2021-04-20T20:33:52.024369152Z", "durationInNanos": 28434944, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58974, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "1fdfb0d6a0c76960"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "1fdfb0d6a0c76960", "traceState": "", "parentSpanId": "a748c29eeb1d7e59", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.231162624Z", "endTime": "2021-04-20T20:33:52.231785216Z", "durationInNanos": 622592, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "18172e3a91f55d39"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "18172e3a91f55d39", "traceState": "", "parentSpanId": "a748c29eeb1d7e59", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.235772416Z", "endTime": "2021-04-20T20:33:52.256177152Z", "durationInNanos": 20404736, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "a748c29eeb1d7e59"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "a748c29eeb1d7e59", "traceState": "", "parentSpanId": "adbedfaf38a87985", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.211242240Z", "endTime": "2021-04-20T20:33:52.259230720Z", "durationInNanos": 47988480, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "adbedfaf38a87985"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "adbedfaf38a87985", "traceState": "", "parentSpanId": "ba003d4618b074f7", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.210340352Z", "endTime": "2021-04-20T20:33:52.262700032Z", "durationInNanos": 52359680, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58988, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "66dd3959b912162c"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "66dd3959b912162c", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.204713472Z", "endTime": "2021-04-20T20:33:52.288004096Z", "durationInNanos": 83290624, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "4543b1bfbb5964c3"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "4543b1bfbb5964c3", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.497326080Z", "endTime": "2021-04-20T20:33:52.532990720Z", "durationInNanos": 35664640, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "45c65220620defaf"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "45c65220620defaf", "traceState": "", "parentSpanId": "b4e1a6127d470651", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.539106304Z", "endTime": "2021-04-20T20:33:52.563575552Z", "durationInNanos": 24469248, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "179c014a060ab428"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "179c014a060ab428", "traceState": "", "parentSpanId": "f6691ab391b0e350", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.598380800Z", "endTime": "2021-04-20T20:33:52.599080704Z", "durationInNanos": 699904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "f6691ab391b0e350"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "f6691ab391b0e350", "traceState": "", "parentSpanId": "f3dc908cffab10fe", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.578200832Z", "endTime": "2021-04-20T20:33:52.603235328Z", "durationInNanos": 25034496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "6a8149f2f3269df9"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "6a8149f2f3269df9", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.614755328Z", "endTime": "2021-04-20T20:33:52.619177472Z", "durationInNanos": 4422144, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c52d1f54270c1a88"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "c52d1f54270c1a88", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.493635840Z", "endTime": "2021-04-20T20:33:52.632568064Z", "durationInNanos": 138932224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "5b1ed6116a19ebcc"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "5b1ed6116a19ebcc", "traceState": "", "parentSpanId": "14148032cdebd6e5", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.698918400Z", "endTime": "2021-04-20T20:33:52.699564800Z", "durationInNanos": 646400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "680639d2b7681a2a"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "680639d2b7681a2a", "traceState": "", "parentSpanId": "d85ef60c6b05ea1e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.675642368Z", "endTime": "2021-04-20T20:33:52.711814144Z", "durationInNanos": 36171776, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f30e9c92926901d9"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "f30e9c92926901d9", "traceState": "", "parentSpanId": "70e7adcb0023b919", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.756263936Z", "endTime": "2021-04-20T20:33:52.785140224Z", "durationInNanos": 28876288, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59024, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "1aa4ab0af82bbbb2"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "1aa4ab0af82bbbb2", "traceState": "", "parentSpanId": "b6b76ad0ea7a18e0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.954985472Z", "endTime": "2021-04-20T20:33:52.978256896Z", "durationInNanos": 23271424, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "b6b76ad0ea7a18e0"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "b6b76ad0ea7a18e0", "traceState": "", "parentSpanId": "bffbe84728e92b6d", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.930167040Z", "endTime": "2021-04-20T20:33:52.981641472Z", "durationInNanos": 51474432, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "68f6536a0523f7f3"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "68f6536a0523f7f3", "traceState": "", "parentSpanId": "2badcc8448bd5c5b", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.215277568Z", "endTime": "2021-04-20T20:33:53.253143808Z", "durationInNanos": 37866240, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "a4030e9ad85b2a92"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "a4030e9ad85b2a92", "traceState": "", "parentSpanId": "057ca06095200357", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.259318272Z", "endTime": "2021-04-20T20:33:53.284444928Z", "durationInNanos": 25126656, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:53.284412416Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "4244f688b5a95a26"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "4244f688b5a95a26", "traceState": "", "parentSpanId": "49bd0e3a571e477d", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.301197056Z", "endTime": "2021-04-20T20:33:53.326327296Z", "durationInNanos": 25130240, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:53.326294016Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "49bd0e3a571e477d"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "49bd0e3a571e477d", "traceState": "", "parentSpanId": "06d1242a51405187", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.300201216Z", "endTime": "2021-04-20T20:33:53.330773248Z", "durationInNanos": 30572032, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId apple", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59056, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "a03d0ff09010abc3"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "a03d0ff09010abc3", "traceState": "", "parentSpanId": "66a2144a58008463", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.211857408Z", "endTime": "2021-04-20T20:33:53.345646848Z", "durationInNanos": 133789440, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "1baf1e42d2eaae2a"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "1baf1e42d2eaae2a", "traceState": "", "parentSpanId": "cefea796ccf54813", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.429764096Z", "endTime": "2021-04-20T20:33:53.493248256Z", "durationInNanos": 63484160, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "1dc7b46c2357c388"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "1dc7b46c2357c388", "traceState": "", "parentSpanId": "2aec9c6345d7c6b3", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.426487808Z", "endTime": "2021-04-20T20:33:53.509910016Z", "durationInNanos": 83422208, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "86b490f5558fa709"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "86b490f5558fa709", "traceState": "", "parentSpanId": "32c7b65db72d6298", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.125418594Z", "endTime": "2021-04-20T20:33:49.126411716Z", "durationInNanos": 993122, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "f8d135e17dd59043"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "f8d135e17dd59043", "traceState": "", "parentSpanId": "1fe046d4f9f3bd13", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.722447259Z", "endTime": "2021-04-20T20:33:51.723605629Z", "durationInNanos": 1158370, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "32c7b65db72d6298"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "32c7b65db72d6298", "traceState": "", "parentSpanId": "d74d48bf3431c487", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.125001550Z", "endTime": "2021-04-20T20:33:49.126513995Z", "durationInNanos": 1512445, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58088, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "50347b6be84490e4"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "50347b6be84490e4", "traceState": "", "parentSpanId": "d03fde256c0d5e87", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.356001691Z", "endTime": "2021-04-20T20:33:49.357803832Z", "durationInNanos": 1802141, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58098, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "d0c7228a8eb81715"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "d0c7228a8eb81715", "traceState": "", "parentSpanId": "268c00835c4cc7ac", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.850001822Z", "endTime": "2021-04-20T20:33:50.851659846Z", "durationInNanos": 1658024, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58174, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "0f929cd09feb717a"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "0f929cd09feb717a", "traceState": "", "parentSpanId": "84584d9e50950ea5", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.818001824Z", "endTime": "2021-04-20T20:33:52.819591628Z", "durationInNanos": 1589804, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58268, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "b272143e732a91e9"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "b272143e732a91e9", "traceState": "", "parentSpanId": "477408f3368f28af", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.995002208Z", "endTime": "2021-04-20T20:33:52.996554316Z", "durationInNanos": 1552108, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58278, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "06e4387a53eec8ae"}}
+{ "traceId": "4626b16656c8131c17bef721f94f39d0", "spanId": "06e4387a53eec8ae", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:19.541728768Z", "endTime": "2021-04-20T20:33:19.544739584Z", "durationInNanos": 3010816, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8086, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 42362, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8086", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
+{ "index":{"_id": "60393741cd2ba5da"}}
+{ "traceId": "5a551c574ba60b0fddee0a98150ad7c6", "spanId": "60393741cd2ba5da", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:20.558674688Z", "endTime": "2021-04-20T20:33:20.561958656Z", "durationInNanos": 3283968, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8085, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 37624, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8085", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
+{ "index":{"_id": "840eaf798fcd7d6a"}}
+{ "traceId": "513e4f752e4411aa6d4b6b35878172f3", "spanId": "840eaf798fcd7d6a", "traceState": "", "parentSpanId": "d3c888f442bdf005", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:29.225169408Z", "endTime": "2021-04-20T20:33:29.237534464Z", "durationInNanos": 12365056, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59546, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
+{ "index":{"_id": "647e42f1b60baba6"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "647e42f1b60baba6", "traceState": "", "parentSpanId": "8e7e103a2e3a040f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:32.582873344Z", "endTime": "2021-04-20T20:33:32.583549440Z", "durationInNanos": 676096, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM Inventory_Items", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "519baeb3e108614d"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "519baeb3e108614d", "traceState": "", "parentSpanId": "65bcaf9c16235fec", "name": "getIntentory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.557999360Z", "endTime": "2021-04-20T20:33:32.590999808Z", "durationInNanos": 33000448, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58316, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_inventory", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "caed30931d6c8826"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "caed30931d6c8826", "traceState": "", "parentSpanId": "88484a1ee3c170cd", "name": "recommend", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.547260416Z", "endTime": "2021-04-20T20:33:32.628968960Z", "durationInNanos": 81708544, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8086, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 42416, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/recommend", "span.attributes.http@host": "localhost:8086", "span.attributes.http@target": "/recommend", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "40c037eaae087000"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "40c037eaae087000", "traceState": "", "parentSpanId": "55d7f80c6aff4ec7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.314483968Z", "endTime": "2021-04-20T20:33:34.349315328Z", "durationInNanos": 34831360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58344, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "ec44bfc9b38f6faf"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "ec44bfc9b38f6faf", "traceState": "", "parentSpanId": "ab460c6800da22bf", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.727146240Z", "endTime": "2021-04-20T20:33:34.727824384Z", "durationInNanos": 678144, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "ab460c6800da22bf"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "ab460c6800da22bf", "traceState": "", "parentSpanId": "066eee06004804d5", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.707429632Z", "endTime": "2021-04-20T20:33:34.731620608Z", "durationInNanos": 24190976, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "066eee06004804d5"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "066eee06004804d5", "traceState": "", "parentSpanId": "bb8e3a8935263a0e", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.706544640Z", "endTime": "2021-04-20T20:33:34.734942208Z", "durationInNanos": 28397568, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58354, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "bb8e3a8935263a0e"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "bb8e3a8935263a0e", "traceState": "", "parentSpanId": "60845ba7d8c2aaf0", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.704376320Z", "endTime": "2021-04-20T20:33:34.739784704Z", "durationInNanos": 35408384, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "99d7b8673d19932d"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "99d7b8673d19932d", "traceState": "", "parentSpanId": "60845ba7d8c2aaf0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.742878464Z", "endTime": "2021-04-20T20:33:34.748727296Z", "durationInNanos": 5848832, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "174b6e4f69dd2d18"}}
+{ "traceId": "9cc5c0acce9b9acc05b1c8d082709609", "spanId": "174b6e4f69dd2d18", "traceState": "", "parentSpanId": "9b3c0b3ed5c876e6", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.171959296Z", "endTime": "2021-04-20T20:33:35.219812352Z", "durationInNanos": 47853056, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "6f9eca809cfd10f4"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "6f9eca809cfd10f4", "traceState": "", "parentSpanId": "1cfde34b0e64708d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.738551040Z", "endTime": "2021-04-20T20:33:35.739376640Z", "durationInNanos": 825600, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "cc1bd6dba046b476"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "cc1bd6dba046b476", "traceState": "", "parentSpanId": "bb9e8ac613f9c314", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.783496704Z", "endTime": "2021-04-20T20:33:35.784163328Z", "durationInNanos": 666624, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "17573d14a639e1d1"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "17573d14a639e1d1", "traceState": "", "parentSpanId": "285b2f9d476d9a6f", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:35.663353600Z", "endTime": "2021-04-20T20:33:35.810676480Z", "durationInNanos": 147322880, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60752, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c2340bad2c8d7620"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "c2340bad2c8d7620", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.660813824Z", "endTime": "2021-04-20T20:33:35.818663168Z", "durationInNanos": 157849344, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7fe759e9e512c8ff"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "7fe759e9e512c8ff", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.099666432Z", "endTime": "2021-04-20T20:33:36.100590592Z", "durationInNanos": 924160, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "3c71472fb76ad5e6"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "3c71472fb76ad5e6", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.107451904Z", "endTime": "2021-04-20T20:33:36.108079616Z", "durationInNanos": 627712, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "8e2e0e3da163fc3b"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "8e2e0e3da163fc3b", "traceState": "", "parentSpanId": "42b721754a8f6168", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.113731328Z", "endTime": "2021-04-20T20:33:36.139224064Z", "durationInNanos": 25492736, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "42b721754a8f6168"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "42b721754a8f6168", "traceState": "", "parentSpanId": "cb2b82acca479730", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.074103296Z", "endTime": "2021-04-20T20:33:36.142439680Z", "durationInNanos": 68336384, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ad7845eabc7145cd"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "ad7845eabc7145cd", "traceState": "", "parentSpanId": "db173bc10299861f", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.155145984Z", "endTime": "2021-04-20T20:33:36.160770816Z", "durationInNanos": 5624832, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "ac0d61f7be00cc09"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "ac0d61f7be00cc09", "traceState": "", "parentSpanId": "4f70367bf3c97d0e", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.574601472Z", "endTime": "2021-04-20T20:33:36.606697728Z", "durationInNanos": 32096256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58414, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "4f70367bf3c97d0e"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "4f70367bf3c97d0e", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.572322816Z", "endTime": "2021-04-20T20:33:36.611627264Z", "durationInNanos": 39304448, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "375cb3ef27c46997"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "375cb3ef27c46997", "traceState": "", "parentSpanId": "b5ef9ef1ecddda5e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.485675264Z", "endTime": "2021-04-20T20:33:36.629994496Z", "durationInNanos": 144319232, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "60019ca1c2f5ab8e"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "60019ca1c2f5ab8e", "traceState": "", "parentSpanId": "d3911d8b057539bb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.481851648Z", "endTime": "2021-04-20T20:33:36.647876864Z", "durationInNanos": 166025216, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a7fcdbe2bf6d6d75"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "a7fcdbe2bf6d6d75", "traceState": "", "parentSpanId": "7c058c08a86fc5a8", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.996497920Z", "endTime": "2021-04-20T20:33:37.070610176Z", "durationInNanos": 74112256, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7c058c08a86fc5a8"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "7c058c08a86fc5a8", "traceState": "", "parentSpanId": "68cf95323b3af152", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.995693312Z", "endTime": "2021-04-20T20:33:37.072949248Z", "durationInNanos": 77255936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60802, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "68cf95323b3af152"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "68cf95323b3af152", "traceState": "", "parentSpanId": "bfcda24f22004149", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.993572608Z", "endTime": "2021-04-20T20:33:37.077576704Z", "durationInNanos": 84004096, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "bfcda24f22004149"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "bfcda24f22004149", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.993322752Z", "endTime": "2021-04-20T20:33:37.080295680Z", "durationInNanos": 86972928, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "8fd6fd77a11f4983"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "8fd6fd77a11f4983", "traceState": "", "parentSpanId": "b4f529ee6fed4e49", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:37.408389376Z", "endTime": "2021-04-20T20:33:37.443986176Z", "durationInNanos": 35596800, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58436, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "71529953e9aa20e1"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "71529953e9aa20e1", "traceState": "", "parentSpanId": "67a615bb3d2aef86", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.544745216Z", "endTime": "2021-04-20T20:33:37.549624064Z", "durationInNanos": 4878848, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "523a0808d6e0be58"}}
+{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "523a0808d6e0be58", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.780772864Z", "endTime": "2021-04-20T20:33:37.882267392Z", "durationInNanos": 101494528, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "aaa95e9f50a4baa3"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "aaa95e9f50a4baa3", "traceState": "", "parentSpanId": "7bc2fe0a60e01dba", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.200260352Z", "endTime": "2021-04-20T20:33:38.226785024Z", "durationInNanos": 26524672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "56925faca063f848"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "56925faca063f848", "traceState": "", "parentSpanId": "1b26c8058d3cd7b6", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.240576512Z", "endTime": "2021-04-20T20:33:38.272510720Z", "durationInNanos": 31934208, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58474, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "36883585e85d1b73"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "36883585e85d1b73", "traceState": "", "parentSpanId": "0f425b86cb459271", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.619970304Z", "endTime": "2021-04-20T20:33:38.653283072Z", "durationInNanos": 33312768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58498, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e8365c37ca6c41a9"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "e8365c37ca6c41a9", "traceState": "", "parentSpanId": "95441fc1d382e48d", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.702615040Z", "endTime": "2021-04-20T20:33:38.707414784Z", "durationInNanos": 4799744, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "cc87be09db83951c"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "cc87be09db83951c", "traceState": "", "parentSpanId": "eb63409f597c3607", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.557328128Z", "endTime": "2021-04-20T20:33:38.718940928Z", "durationInNanos": 161612800, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "eb63409f597c3607"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "eb63409f597c3607", "traceState": "", "parentSpanId": "07b4d48cb660e9cc", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.556882688Z", "endTime": "2021-04-20T20:33:38.734543616Z", "durationInNanos": 177660928, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "d250018f35242056"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "d250018f35242056", "traceState": "", "parentSpanId": "c9b6a51576561f98", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.065582317Z", "endTime": "2021-04-20T20:33:37.066913Z", "durationInNanos": 1330683, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "7b78d2bea411b2fe"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "7b78d2bea411b2fe", "traceState": "", "parentSpanId": "0a9ab07c9f5e7d29", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.359002058Z", "endTime": "2021-04-20T20:33:34.361727904Z", "durationInNanos": 2725846, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57588, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "7145d5e8e15acfb7"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "7145d5e8e15acfb7", "traceState": "", "parentSpanId": "99d7b8673d19932d", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.745001766Z", "endTime": "2021-04-20T20:33:34.747694532Z", "durationInNanos": 2692766, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57598, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "474039eb574aec04"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "474039eb574aec04", "traceState": "", "parentSpanId": "ad7845eabc7145cd", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.157001583Z", "endTime": "2021-04-20T20:33:36.159234806Z", "durationInNanos": 2233223, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57638, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "77243c434c2fcb1f"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "77243c434c2fcb1f", "traceState": "", "parentSpanId": "937fb8345b252adb", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.617002014Z", "endTime": "2021-04-20T20:33:36.619561838Z", "durationInNanos": 2559824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57658, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "fd955727cb8de558"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "fd955727cb8de558", "traceState": "", "parentSpanId": "f211085459dee231", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.284002091Z", "endTime": "2021-04-20T20:33:38.286466012Z", "durationInNanos": 2463921, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57720, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "c1e60aa906af446c"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "c1e60aa906af446c", "traceState": "", "parentSpanId": "c5280d05b1704e38", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.302001808Z", "endTime": "2021-04-20T20:33:38.303866754Z", "durationInNanos": 1864946, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57722, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "f251b6b23136a553"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "f251b6b23136a553", "traceState": "", "parentSpanId": "76ac0909a315d25c", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.726001732Z", "endTime": "2021-04-20T20:33:38.728225906Z", "durationInNanos": 2224174, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57748, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "3746bae316ced457"}}
+{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "3746bae316ced457", "traceState": "", "parentSpanId": "8eafdbb08ef33fac", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:39.773298688Z", "endTime": "2021-04-20T20:33:39.775022848Z", "durationInNanos": 1724160, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "0afb5a2b1848c74b"}}
+{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "0afb5a2b1848c74b", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.747136Z", "endTime": "2021-04-20T20:33:39.807513856Z", "durationInNanos": 60377856, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "669d2b7892e6854c"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "669d2b7892e6854c", "traceState": "", "parentSpanId": "9253cd2f27e55a6f", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.228339200Z", "endTime": "2021-04-20T20:33:40.299048192Z", "durationInNanos": 70708992, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "59443367c68e77d9"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "59443367c68e77d9", "traceState": "", "parentSpanId": "c3bb9b0cacfb19ea", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.185568512Z", "endTime": "2021-04-20T20:33:41.234750208Z", "durationInNanos": 49181696, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "3d3423c981805776"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "3d3423c981805776", "traceState": "", "parentSpanId": "a4ba523cda11d1d3", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.246229760Z", "endTime": "2021-04-20T20:33:41.251002880Z", "durationInNanos": 4773120, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e3496923e8587b46"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "e3496923e8587b46", "traceState": "", "parentSpanId": "6b60bf20aca25776", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:41.625234688Z", "endTime": "2021-04-20T20:33:41.654554624Z", "durationInNanos": 29319936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58576, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "18af310c32c71ea5"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "18af310c32c71ea5", "traceState": "", "parentSpanId": "915cceedf89bd5f3", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.619891200Z", "endTime": "2021-04-20T20:33:41.677285120Z", "durationInNanos": 57393920, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7a5994c2d61252d8"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "7a5994c2d61252d8", "traceState": "", "parentSpanId": "903ebe485e8ce58d", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.001465600Z", "endTime": "2021-04-20T20:33:42.054217216Z", "durationInNanos": 52751616, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58586, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "2786ea5cfba1d51c"}}
+{ "traceId": "552aa3363bf275a248b131406edf735d", "spanId": "2786ea5cfba1d51c", "traceState": "", "parentSpanId": "e8aeb63bfa118068", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.996101888Z", "endTime": "2021-04-20T20:33:42.080325120Z", "durationInNanos": 84223232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/pay_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "694e40f773666591"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "694e40f773666591", "traceState": "", "parentSpanId": "de34ef4183a4705b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.522945280Z", "endTime": "2021-04-20T20:33:42.523687680Z", "durationInNanos": 742400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "7cd34262856a4d72"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "7cd34262856a4d72", "traceState": "", "parentSpanId": "d2b2b41a16075705", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.604768512Z", "endTime": "2021-04-20T20:33:42.605615360Z", "durationInNanos": 846848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "5bd2b2161742dcd5"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "5bd2b2161742dcd5", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.623602688Z", "endTime": "2021-04-20T20:33:42.628299008Z", "durationInNanos": 4696320, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "4eaffcf10b0ddc1b"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "4eaffcf10b0ddc1b", "traceState": "", "parentSpanId": "5204fe33a94fc5e5", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.495094784Z", "endTime": "2021-04-20T20:33:42.651653888Z", "durationInNanos": 156559104, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59848, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9645c99068238c29"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "9645c99068238c29", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.492572416Z", "endTime": "2021-04-20T20:33:42.660122112Z", "durationInNanos": 167549696, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "080f360f30d5f04d"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "080f360f30d5f04d", "traceState": "", "parentSpanId": "01b11afabc7fdc7f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.411759104Z", "endTime": "2021-04-20T20:33:43.413591296Z", "durationInNanos": 1832192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "01b11afabc7fdc7f"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "01b11afabc7fdc7f", "traceState": "", "parentSpanId": "54419fc75e901eee", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.391958528Z", "endTime": "2021-04-20T20:33:43.440197888Z", "durationInNanos": 48239360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "54419fc75e901eee"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "54419fc75e901eee", "traceState": "", "parentSpanId": "85fb245e31172689", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.391038976Z", "endTime": "2021-04-20T20:33:43.443544064Z", "durationInNanos": 52505088, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58618, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "85fb245e31172689"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "85fb245e31172689", "traceState": "", "parentSpanId": "a0bed7d434593b60", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.388828416Z", "endTime": "2021-04-20T20:33:43.448487936Z", "durationInNanos": 59659520, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "36695d818f9b4e9a"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "36695d818f9b4e9a", "traceState": "", "parentSpanId": "5268497625ace4e0", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.387825664Z", "endTime": "2021-04-20T20:33:43.460932608Z", "durationInNanos": 73106944, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60994, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "2bacaf900ae368c7"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "2bacaf900ae368c7", "traceState": "", "parentSpanId": "5d8912365e6688f3", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.845935616Z", "endTime": "2021-04-20T20:33:43.847112448Z", "durationInNanos": 1176832, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "cf38f810fff59bb3"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "cf38f810fff59bb3", "traceState": "", "parentSpanId": "5d8912365e6688f3", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.850872832Z", "endTime": "2021-04-20T20:33:43.871734272Z", "durationInNanos": 20861440, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "37628f7fdcf79dbb"}}
+{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "37628f7fdcf79dbb", "traceState": "", "parentSpanId": "cf2a67c23dc23bab", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.791471041Z", "endTime": "2021-04-20T20:33:39.792596934Z", "durationInNanos": 1125893, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "dd0a9b2bcbdcdbb6"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "dd0a9b2bcbdcdbb6", "traceState": "", "parentSpanId": "a981fd033e3a7491", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.248690371Z", "endTime": "2021-04-20T20:33:41.249957195Z", "durationInNanos": 1266824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "3230880363166a80"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "3230880363166a80", "traceState": "", "parentSpanId": "f405f62e61d4181f", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.643464807Z", "endTime": "2021-04-20T20:33:42.644564500Z", "durationInNanos": 1099693, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "1fbcd1691508fa92"}}
+{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "1fbcd1691508fa92", "traceState": "", "parentSpanId": "c519a467435258a0", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.859001828Z", "endTime": "2021-04-20T20:33:40.860862299Z", "durationInNanos": 1860471, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57798, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "570073e77e68be9d"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "570073e77e68be9d", "traceState": "", "parentSpanId": "72fd9aa427e26550", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.185529088Z", "endTime": "2021-04-20T20:33:44.218529024Z", "durationInNanos": 32999936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "2311bcf70d68331c"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "2311bcf70d68331c", "traceState": "", "parentSpanId": "c63088be2f211cf7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.277222400Z", "endTime": "2021-04-20T20:33:44.312690432Z", "durationInNanos": 35468032, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58648, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "885e54cf2034b9f4"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "885e54cf2034b9f4", "traceState": "", "parentSpanId": "104a8f2719108aaf", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.181856512Z", "endTime": "2021-04-20T20:33:44.328167424Z", "durationInNanos": 146310912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "104a8f2719108aaf"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "104a8f2719108aaf", "traceState": "", "parentSpanId": "c85e5dec4106a06a", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.181052672Z", "endTime": "2021-04-20T20:33:44.330511104Z", "durationInNanos": 149458432, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32782, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "504e26f11e5bb1ae"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "504e26f11e5bb1ae", "traceState": "", "parentSpanId": "0ee38170cee8fb5c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.594721792Z", "endTime": "2021-04-20T20:33:44.599331328Z", "durationInNanos": 4609536, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "93047965b18da903"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "93047965b18da903", "traceState": "", "parentSpanId": "7359981596903c3f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.966868736Z", "endTime": "2021-04-20T20:33:44.989101312Z", "durationInNanos": 22232576, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "9ca0bf86196899bc"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "9ca0bf86196899bc", "traceState": "", "parentSpanId": "ead17a7f0d4e34ed", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.943505664Z", "endTime": "2021-04-20T20:33:45.011987456Z", "durationInNanos": 68481792, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "92e84113ddc59da5"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "92e84113ddc59da5", "traceState": "", "parentSpanId": "dcf70445f2a2cd40", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.654626048Z", "endTime": "2021-04-20T20:33:45.655334912Z", "durationInNanos": 708864, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "dcf70445f2a2cd40"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "dcf70445f2a2cd40", "traceState": "", "parentSpanId": "0c64ae315abfd656", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.634566144Z", "endTime": "2021-04-20T20:33:45.659138816Z", "durationInNanos": 24572672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "0c64ae315abfd656"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "0c64ae315abfd656", "traceState": "", "parentSpanId": "cf25277706dc2439", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.633674752Z", "endTime": "2021-04-20T20:33:45.662507776Z", "durationInNanos": 28833024, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58692, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9bdbac7482af31f3"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "9bdbac7482af31f3", "traceState": "", "parentSpanId": "ded3687b9758bf59", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.584570112Z", "endTime": "2021-04-20T20:33:45.719764480Z", "durationInNanos": 135194368, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32832, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "8e8e5e8bd88c11b5"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "8e8e5e8bd88c11b5", "traceState": "", "parentSpanId": "69af53e3494bca1c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.943921408Z", "endTime": "2021-04-20T20:33:45.965064192Z", "durationInNanos": 21142784, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "69af53e3494bca1c"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "69af53e3494bca1c", "traceState": "", "parentSpanId": "3a025025e0a3b1fa", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.913632256Z", "endTime": "2021-04-20T20:33:45.968429568Z", "durationInNanos": 54797312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ea4bcbaf2a9a6fa3"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "ea4bcbaf2a9a6fa3", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.907184128Z", "endTime": "2021-04-20T20:33:45.997188352Z", "durationInNanos": 90004224, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "5edd047783ce31e6"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "5edd047783ce31e6", "traceState": "", "parentSpanId": "9a880188bcb44cda", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.196210944Z", "endTime": "2021-04-20T20:33:46.228526592Z", "durationInNanos": 32315648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58722, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "6f7eafee7d68115c"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "6f7eafee7d68115c", "traceState": "", "parentSpanId": "203faf4d95696dc4", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.240107008Z", "endTime": "2021-04-20T20:33:46.267194368Z", "durationInNanos": 27087360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "22b1d496a103d5d4"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "22b1d496a103d5d4", "traceState": "", "parentSpanId": "30652f6f8b511470", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.151774720Z", "endTime": "2021-04-20T20:33:46.278444288Z", "durationInNanos": 126669568, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "e270a32c23bb3d64"}}
+{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "e270a32c23bb3d64", "traceState": "", "parentSpanId": "b9eb99e7f12a273f", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.505004800Z", "endTime": "2021-04-20T20:33:46.555533056Z", "durationInNanos": 50528256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "a3ff3a8683434406"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "a3ff3a8683434406", "traceState": "", "parentSpanId": "c78ae9d1aa24d379", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.821765888Z", "endTime": "2021-04-20T20:33:46.822455808Z", "durationInNanos": 689920, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "63f9d7eb1b86d29a"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "63f9d7eb1b86d29a", "traceState": "", "parentSpanId": "43dc7bc2e05bfa0f", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.800928512Z", "endTime": "2021-04-20T20:33:46.835864064Z", "durationInNanos": 34935552, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58744, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "43dc7bc2e05bfa0f"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "43dc7bc2e05bfa0f", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.798465280Z", "endTime": "2021-04-20T20:33:46.840932096Z", "durationInNanos": 42466816, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "fddac8b6501344bf"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "fddac8b6501344bf", "traceState": "", "parentSpanId": "3b2b065511029f95", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.866892288Z", "endTime": "2021-04-20T20:33:46.867537408Z", "durationInNanos": 645120, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "759ba13f98ab3fc6"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "759ba13f98ab3fc6", "traceState": "", "parentSpanId": "fa4a423fd5b1089d", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.846178304Z", "endTime": "2021-04-20T20:33:46.874823424Z", "durationInNanos": 28645120, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58748, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "fa4a423fd5b1089d"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "fa4a423fd5b1089d", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.843851264Z", "endTime": "2021-04-20T20:33:46.879571200Z", "durationInNanos": 35719936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f0aeb9700f457880"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "f0aeb9700f457880", "traceState": "", "parentSpanId": "51c0b6f4525f8ce7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.882574848Z", "endTime": "2021-04-20T20:33:46.918776576Z", "durationInNanos": 36201728, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "51c0b6f4525f8ce7"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "51c0b6f4525f8ce7", "traceState": "", "parentSpanId": "46804b074d510e22", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.798070016Z", "endTime": "2021-04-20T20:33:46.929501952Z", "durationInNanos": 131431936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "4fb9849a6b80b6f2"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "4fb9849a6b80b6f2", "traceState": "", "parentSpanId": "8d4b7a48cb7ee8e9", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.263351552Z", "endTime": "2021-04-20T20:33:47.264209664Z", "durationInNanos": 858112, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "f78dbd14cda8862e"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "f78dbd14cda8862e", "traceState": "", "parentSpanId": "b974c6840493462f", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.230816768Z", "endTime": "2021-04-20T20:33:47.274358784Z", "durationInNanos": 43542016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58768, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "3e1ca23a1316a089"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "3e1ca23a1316a089", "traceState": "", "parentSpanId": "9995da51cebe7887", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.188528128Z", "endTime": "2021-04-20T20:33:47.323207424Z", "durationInNanos": 134679296, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "35a5641a51a07620"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "35a5641a51a07620", "traceState": "", "parentSpanId": "f707df9bafaf7974", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.184227840Z", "endTime": "2021-04-20T20:33:47.335330816Z", "durationInNanos": 151102976, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60014, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "5b03c5aa49169de7"}}
+{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "5b03c5aa49169de7", "traceState": "", "parentSpanId": "153b191f5bba208f", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.480588800Z", "endTime": "2021-04-20T20:33:47.490298112Z", "durationInNanos": 9709312, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32926, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
+{ "index":{"_id": "a0333ab0c0fb425e"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "a0333ab0c0fb425e", "traceState": "", "parentSpanId": "e36a01c310db6537", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.777365760Z", "endTime": "2021-04-20T20:33:47.806075648Z", "durationInNanos": 28709888, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58788, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e36a01c310db6537"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "e36a01c310db6537", "traceState": "", "parentSpanId": "b7db1195f7777f37", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.775088640Z", "endTime": "2021-04-20T20:33:47.810972160Z", "durationInNanos": 35883520, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "246d5a128abc0323"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "246d5a128abc0323", "traceState": "", "parentSpanId": "0adbc627a3ff01db", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.856003328Z", "endTime": "2021-04-20T20:33:47.880837376Z", "durationInNanos": 24834048, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "b7db1195f7777f37"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "b7db1195f7777f37", "traceState": "", "parentSpanId": "48c5f132edd1dce1", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.774677248Z", "endTime": "2021-04-20T20:33:47.900943872Z", "durationInNanos": 126266624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "8d13c5fb5cb910ab"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "8d13c5fb5cb910ab", "traceState": "", "parentSpanId": "ebfe1ad9b112ca2a", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.771634688Z", "endTime": "2021-04-20T20:33:47.907790080Z", "durationInNanos": 136155392, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "36362df397ac500d"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "36362df397ac500d", "traceState": "", "parentSpanId": "29749eb615c7cf76", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.093012480Z", "endTime": "2021-04-20T20:33:48.128655104Z", "durationInNanos": 35642624, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "29749eb615c7cf76"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "29749eb615c7cf76", "traceState": "", "parentSpanId": "9a8427df12be8522", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.092771840Z", "endTime": "2021-04-20T20:33:48.138572032Z", "durationInNanos": 45800192, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "60b801fae48abf9b"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "60b801fae48abf9b", "traceState": "", "parentSpanId": "3e916e70241c5f31", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.089861120Z", "endTime": "2021-04-20T20:33:48.145265920Z", "durationInNanos": 55404800, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "fc52a63dddb6c78e"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "fc52a63dddb6c78e", "traceState": "", "parentSpanId": "a7ef8140aea6adc9", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.767165440Z", "endTime": "2021-04-20T20:33:48.771305728Z", "durationInNanos": 4140288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a7ef8140aea6adc9"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "a7ef8140aea6adc9", "traceState": "", "parentSpanId": "f0839669f041b029", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.727941632Z", "endTime": "2021-04-20T20:33:48.774041600Z", "durationInNanos": 46099968, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "e038c5aba828ea58"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "e038c5aba828ea58", "traceState": "", "parentSpanId": "658da2faba59acd9", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.023798016Z", "endTime": "2021-04-20T20:33:49.024448256Z", "durationInNanos": 650240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "81de5d2c6aa0859e"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "81de5d2c6aa0859e", "traceState": "", "parentSpanId": "0c1e1c234af592e4", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.042136064Z", "endTime": "2021-04-20T20:33:49.071018496Z", "durationInNanos": 28882432, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58840, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e25b39ceacb30b75"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "e25b39ceacb30b75", "traceState": "", "parentSpanId": "fec494ea1cd015e3", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.301444832Z", "endTime": "2021-04-20T20:33:45.302604111Z", "durationInNanos": 1159279, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "a1339d62f81ccd32"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "a1339d62f81ccd32", "traceState": "", "parentSpanId": "2ac8b4cda3c0f1f9", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.711423559Z", "endTime": "2021-04-20T20:33:45.712615012Z", "durationInNanos": 1191453, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "fdbb1f2f7b488e87"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "fdbb1f2f7b488e87", "traceState": "", "parentSpanId": "75432a4e251c77c6", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.982518483Z", "endTime": "2021-04-20T20:33:45.983665774Z", "durationInNanos": 1147291, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "3ee4a8601f798b23"}}
+{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "3ee4a8601f798b23", "traceState": "", "parentSpanId": "74dbc2be658b50d8", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.456438616Z", "endTime": "2021-04-20T20:33:48.457460497Z", "durationInNanos": 1021881, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "552e8512fb52ccb5"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "552e8512fb52ccb5", "traceState": "", "parentSpanId": "504e26f11e5bb1ae", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.596001537Z", "endTime": "2021-04-20T20:33:44.597771774Z", "durationInNanos": 1770237, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57902, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "11f0fc7fd6fc8ef7"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "11f0fc7fd6fc8ef7", "traceState": "", "parentSpanId": "b45e32302ccd4555", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.133001853Z", "endTime": "2021-04-20T20:33:48.134747430Z", "durationInNanos": 1745577, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58050, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "6436b12426e22058"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "6436b12426e22058", "traceState": "", "parentSpanId": "fc52a63dddb6c78e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.769001550Z", "endTime": "2021-04-20T20:33:48.770509554Z", "durationInNanos": 1508004, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58070, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "be8803ab43db27ca"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "be8803ab43db27ca", "traceState": "", "parentSpanId": "1ca472e346ee563d", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.084217344Z", "endTime": "2021-04-20T20:33:49.111971584Z", "durationInNanos": 27754240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "27d4fe07134ea308"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "27d4fe07134ea308", "traceState": "", "parentSpanId": "6de234553c12cdd0", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.999261952Z", "endTime": "2021-04-20T20:33:49.132644864Z", "durationInNanos": 133382912, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32980, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7ab01768aa773b1c"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "7ab01768aa773b1c", "traceState": "", "parentSpanId": "c7c175f4366ce130", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.318971392Z", "endTime": "2021-04-20T20:33:49.340009216Z", "durationInNanos": 21037824, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "1e69961f46e59586"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "1e69961f46e59586", "traceState": "", "parentSpanId": "73d85e6251f927f6", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.288094720Z", "endTime": "2021-04-20T20:33:49.346589952Z", "durationInNanos": 58495232, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58854, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a4790e6461fa0d5d"}}
+{ "traceId": "da0666d73c1645d392576e56619d8c6e", "spanId": "a4790e6461fa0d5d", "traceState": "", "parentSpanId": "8979ca2f03690516", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.284838912Z", "endTime": "2021-04-20T20:33:49.364374528Z", "durationInNanos": 79535616, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32998, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c4eb12c87b56bbaf"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "c4eb12c87b56bbaf", "traceState": "", "parentSpanId": "b7362733de8bfa9c", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.527205120Z", "endTime": "2021-04-20T20:33:49.551947008Z", "durationInNanos": 24741888, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:49.551908096Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "b7362733de8bfa9c"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "b7362733de8bfa9c", "traceState": "", "parentSpanId": "9be2ff98ca6d0261", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.526326272Z", "endTime": "2021-04-20T20:33:49.556307200Z", "durationInNanos": 29980928, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58866, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "9be2ff98ca6d0261"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "9be2ff98ca6d0261", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.523984384Z", "endTime": "2021-04-20T20:33:49.561157120Z", "durationInNanos": 37172736, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "bb41f245f32492e4"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "bb41f245f32492e4", "traceState": "", "parentSpanId": "6025c3c1f9ee5054", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.517226496Z", "endTime": "2021-04-20T20:33:49.661549056Z", "durationInNanos": 144322560, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "2c3fe2ecd7602e0b"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "2c3fe2ecd7602e0b", "traceState": "", "parentSpanId": "ecc02e73350ce790", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.850896896Z", "endTime": "2021-04-20T20:33:49.902683392Z", "durationInNanos": 51786496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58882, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "3b0e8b5888901f7b"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "3b0e8b5888901f7b", "traceState": "", "parentSpanId": "de9f1128bf12b7b9", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.910390784Z", "endTime": "2021-04-20T20:33:49.915180544Z", "durationInNanos": 4789760, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c6621138316a73b8"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "c6621138316a73b8", "traceState": "", "parentSpanId": "6f5a1a55f4c950f0", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.221707008Z", "endTime": "2021-04-20T20:33:50.250929920Z", "durationInNanos": 29222912, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58900, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "6f5a1a55f4c950f0"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "6f5a1a55f4c950f0", "traceState": "", "parentSpanId": "d18bdbb97967e206", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.219329024Z", "endTime": "2021-04-20T20:33:50.255876352Z", "durationInNanos": 36547328, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d18bdbb97967e206"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "d18bdbb97967e206", "traceState": "", "parentSpanId": "3b639def2d6ec40f", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.141257984Z", "endTime": "2021-04-20T20:33:50.267165184Z", "durationInNanos": 125907200, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "6a539e36635daed1"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "6a539e36635daed1", "traceState": "", "parentSpanId": "13bed71d66dcc038", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.480547328Z", "endTime": "2021-04-20T20:33:50.509742080Z", "durationInNanos": 29194752, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58912, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e282094546b98e61"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "e282094546b98e61", "traceState": "", "parentSpanId": "3a565f7129913c17", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.477368832Z", "endTime": "2021-04-20T20:33:50.527277568Z", "durationInNanos": 49908736, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33056, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c80dc4c948d060d2"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "c80dc4c948d060d2", "traceState": "", "parentSpanId": "7e0f8516534902ba", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.727715584Z", "endTime": "2021-04-20T20:33:50.764667904Z", "durationInNanos": 36952320, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e6af061aa53f5621"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "e6af061aa53f5621", "traceState": "", "parentSpanId": "ecc0e3f8be5250dd", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.812071936Z", "endTime": "2021-04-20T20:33:50.836778496Z", "durationInNanos": 24706560, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "268c00835c4cc7ac"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "268c00835c4cc7ac", "traceState": "", "parentSpanId": "7e0f8516534902ba", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.848304640Z", "endTime": "2021-04-20T20:33:50.852795392Z", "durationInNanos": 4490752, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "aaa75101bed92d1a"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "aaa75101bed92d1a", "traceState": "", "parentSpanId": "e9893407bba95bf0", "name": "getCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.138495232Z", "endTime": "2021-04-20T20:33:51.166544384Z", "durationInNanos": 28049152, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58940, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/get_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "bf2482df930950bb"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "bf2482df930950bb", "traceState": "", "parentSpanId": "0068b98ffc99f9ea", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.135342336Z", "endTime": "2021-04-20T20:33:51.183588864Z", "durationInNanos": 48246528, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33084, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "93330439f7f89167"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "93330439f7f89167", "traceState": "", "parentSpanId": "9b81a0201a53b84c", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.683300864Z", "endTime": "2021-04-20T20:33:51.708692992Z", "durationInNanos": 25392128, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "a9ed253bbf36e70e"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "a9ed253bbf36e70e", "traceState": "", "parentSpanId": "a5a0c83096c8fa20", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.016589056Z", "endTime": "2021-04-20T20:33:52.017283328Z", "durationInNanos": 694272, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "6576e80159aee6b8"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "6576e80159aee6b8", "traceState": "", "parentSpanId": "71e8453fb0ed5faf", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.953919744Z", "endTime": "2021-04-20T20:33:52.078983680Z", "durationInNanos": 125063936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "f8aedbcbab807a78"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "f8aedbcbab807a78", "traceState": "", "parentSpanId": "ed7415d8c9c25969", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.207869440Z", "endTime": "2021-04-20T20:33:52.278209280Z", "durationInNanos": 70339840, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ed7415d8c9c25969"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "ed7415d8c9c25969", "traceState": "", "parentSpanId": "0db04213ba31cb79", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.207073792Z", "endTime": "2021-04-20T20:33:52.280379136Z", "durationInNanos": 73305344, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33132, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "702250f453a02be6"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "702250f453a02be6", "traceState": "", "parentSpanId": "4acae5e4234f52f8", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.496930560Z", "endTime": "2021-04-20T20:33:52.623046656Z", "durationInNanos": 126116096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "84584d9e50950ea5"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "84584d9e50950ea5", "traceState": "", "parentSpanId": "d85ef60c6b05ea1e", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.815784192Z", "endTime": "2021-04-20T20:33:52.820143872Z", "durationInNanos": 4359680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e0514a47c90c0ead"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "e0514a47c90c0ead", "traceState": "", "parentSpanId": "d620278613ba1273", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.674479616Z", "endTime": "2021-04-20T20:33:52.825445632Z", "durationInNanos": 150966016, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33160, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "dfd4cc33b9f49d74"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "dfd4cc33b9f49d74", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.672014080Z", "endTime": "2021-04-20T20:33:52.833018624Z", "durationInNanos": 161004544, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "84e395f144998c01"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "84e395f144998c01", "traceState": "", "parentSpanId": "b6b76ad0ea7a18e0", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.949800192Z", "endTime": "2021-04-20T20:33:52.951031040Z", "durationInNanos": 1230848, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "7e35a93ae1f1d3dc"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "7e35a93ae1f1d3dc", "traceState": "", "parentSpanId": "a77612b8a846894a", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.926126336Z", "endTime": "2021-04-20T20:33:53.003924224Z", "durationInNanos": 77797888, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33178, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a77612b8a846894a"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "a77612b8a846894a", "traceState": "", "parentSpanId": "36bf8ffe6bfab949", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.923979776Z", "endTime": "2021-04-20T20:33:53.008655360Z", "durationInNanos": 84675584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "36bf8ffe6bfab949"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "36bf8ffe6bfab949", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.923733504Z", "endTime": "2021-04-20T20:33:53.011512832Z", "durationInNanos": 87779328, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "057ca06095200357"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "057ca06095200357", "traceState": "", "parentSpanId": "ab2cfda3f66cd29a", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.258444032Z", "endTime": "2021-04-20T20:33:53.288954112Z", "durationInNanos": 30510080, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59050, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "66a2144a58008463"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "66a2144a58008463", "traceState": "", "parentSpanId": "79e7e8f4a6b9cfd6", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.211445504Z", "endTime": "2021-04-20T20:33:53.348402432Z", "durationInNanos": 136956928, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7c1551bf8ecff1e9"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "7c1551bf8ecff1e9", "traceState": "", "parentSpanId": "1baf1e42d2eaae2a", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.432177920Z", "endTime": "2021-04-20T20:33:53.488074240Z", "durationInNanos": 55896320, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59064, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d074c89b98685510"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "d074c89b98685510", "traceState": "", "parentSpanId": "7b337ab41060959b", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.912560857Z", "endTime": "2021-04-20T20:33:49.913841981Z", "durationInNanos": 1281124, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "8d1a3be816dc5afe"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "8d1a3be816dc5afe", "traceState": "", "parentSpanId": "391c448e02ace429", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.073446568Z", "endTime": "2021-04-20T20:33:52.074477704Z", "durationInNanos": 1031136, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-3", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "92b74f59ddd54783"}}
+{ "traceId": "588f0d3438674277899b1f0bf2f2ebf2", "spanId": "92b74f59ddd54783", "traceState": "", "parentSpanId": "", "name": "mysql", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:15.007993856Z", "endTime": "2021-04-20T20:33:15.024957696Z", "durationInNanos": 16963840, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "mysql", "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "", "span.attributes.db@statement": "CREATE TABLE `User_Carts` ( `ItemId` varchar(16) NOT NULL, `TotalQty` int(11) NOT NULL, PRIMARY KEY (`ItemId`)) ENGINE=InnoDB", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "25af21b469c032b3"}}
+{ "traceId": "64398afff83d4ce40feb342b493d03cf", "spanId": "25af21b469c032b3", "traceState": "", "parentSpanId": "", "name": "HTTP GET", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:17.441215232Z", "endTime": "2021-04-20T20:33:17.444359680Z", "durationInNanos": 3144448, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "HTTP GET", "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "NOT FOUND", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "curl/7.61.1", "span.attributes.net@peer@port": 47996, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 404 }
+{ "index":{"_id": "6c89443d5e23abf3"}}
+{ "traceId": "df5948afbb8aa0bdd587a5b81d7589da", "spanId": "6c89443d5e23abf3", "traceState": "", "parentSpanId": "c9ffe4c0af278e39", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:28.392941824Z", "endTime": "2021-04-20T20:33:28.467089152Z", "durationInNanos": 74147328, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "96e7fdedd82ab53c"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "96e7fdedd82ab53c", "traceState": "", "parentSpanId": "2c122c9d8977d38d", "name": "verify_login", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:32.542609152Z", "endTime": "2021-04-20T20:33:32.542644224Z", "durationInNanos": 35072, "serviceName": "authentication", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139949516139040", "resource.attributes.service@name": "authentication", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "71869e6acbd9b84e"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "71869e6acbd9b84e", "traceState": "", "parentSpanId": "6921db03f367dc79", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:32.548511744Z", "endTime": "2021-04-20T20:33:32.614019584Z", "durationInNanos": 65507840, "serviceName": "recommendation", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/read_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140018306314192", "resource.attributes.service@name": "recommendation", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "39d9f21d9865f9e6"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "39d9f21d9865f9e6", "traceState": "", "parentSpanId": "", "name": "load_main_screen", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:32.538752Z", "endTime": "2021-04-20T20:33:32.652837376Z", "durationInNanos": 114085376, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "load_main_screen", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "2a1b45c16eaad09c"}}
+{ "traceId": "a80cb852f0c27762cfa923836bc5fe88", "spanId": "2a1b45c16eaad09c", "traceState": "", "parentSpanId": "9ba40f97c2ae86a7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:33.447434240Z", "endTime": "2021-04-20T20:33:33.454592512Z", "durationInNanos": 7158272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9ba40f97c2ae86a7"}}
+{ "traceId": "a80cb852f0c27762cfa923836bc5fe88", "spanId": "9ba40f97c2ae86a7", "traceState": "", "parentSpanId": "daf5a14650228970", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:33.446325504Z", "endTime": "2021-04-20T20:33:33.457898240Z", "durationInNanos": 11572736, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "SERVICE UNAVAILABLE", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60706, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 503 }
+{ "index":{"_id": "84fe46385d17b02c"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "84fe46385d17b02c", "traceState": "", "parentSpanId": "e1bc8cfc3ceb0aaf", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.601002072Z", "endTime": "2021-04-20T20:33:32.603410081Z", "durationInNanos": 2408009, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57560, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "2a5ae161952463e2"}}
+{ "traceId": "d37d709d5695f213e4ca41ac874c00bc", "spanId": "2a5ae161952463e2", "traceState": "", "parentSpanId": "ff013ccfd9d58cec", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:32.638002124Z", "endTime": "2021-04-20T20:33:32.640473313Z", "durationInNanos": 2471189, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57564, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "d4255abf68ac0402"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "d4255abf68ac0402", "traceState": "", "parentSpanId": "31a0c82890fa754b", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.222288128Z", "endTime": "2021-04-20T20:33:34.254911488Z", "durationInNanos": 32623360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "be5b2f7a197c64cf"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "be5b2f7a197c64cf", "traceState": "", "parentSpanId": "97aa186489e038e0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.219140864Z", "endTime": "2021-04-20T20:33:34.263220992Z", "durationInNanos": 44080128, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e46a02e7b9ed8ecf"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "e46a02e7b9ed8ecf", "traceState": "", "parentSpanId": "c17b37664943c0a0", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.269251584Z", "endTime": "2021-04-20T20:33:34.300863232Z", "durationInNanos": 31611648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "c17b37664943c0a0"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "c17b37664943c0a0", "traceState": "", "parentSpanId": "e5fd4823e84df1a0", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:34.268306688Z", "endTime": "2021-04-20T20:33:34.304210944Z", "durationInNanos": 35904256, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58340, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "55d7f80c6aff4ec7"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "55d7f80c6aff4ec7", "traceState": "", "parentSpanId": "97aa186489e038e0", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:34.312219392Z", "endTime": "2021-04-20T20:33:34.354283520Z", "durationInNanos": 42064128, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c0cb4dc5b7b1db59"}}
+{ "traceId": "9cc5c0acce9b9acc05b1c8d082709609", "spanId": "c0cb4dc5b7b1db59", "traceState": "", "parentSpanId": "16d6fb920c980921", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.231047680Z", "endTime": "2021-04-20T20:33:35.236322816Z", "durationInNanos": 5275136, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "6f3b8af3574d67d8"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "6f3b8af3574d67d8", "traceState": "", "parentSpanId": "d7d09b29635c42d0", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.667787520Z", "endTime": "2021-04-20T20:33:35.699713792Z", "durationInNanos": 31926272, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1cfde34b0e64708d"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "1cfde34b0e64708d", "traceState": "", "parentSpanId": "16a087ca75a1c1ae", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.714154496Z", "endTime": "2021-04-20T20:33:35.744516352Z", "durationInNanos": 30361856, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "c607c3f259c8a65b"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "c607c3f259c8a65b", "traceState": "", "parentSpanId": "bb9e8ac613f9c314", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.778753792Z", "endTime": "2021-04-20T20:33:35.779580160Z", "durationInNanos": 826368, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "bb9e8ac613f9c314"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "bb9e8ac613f9c314", "traceState": "", "parentSpanId": "f756b2ab52d63952", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:35.758739968Z", "endTime": "2021-04-20T20:33:35.789022208Z", "durationInNanos": 30282240, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "f19d16050494663f"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "f19d16050494663f", "traceState": "", "parentSpanId": "7d7dc4421190f8f1", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:35.755664896Z", "endTime": "2021-04-20T20:33:35.797313792Z", "durationInNanos": 41648896, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "4d9ad162398612ca"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "4d9ad162398612ca", "traceState": "", "parentSpanId": "db173bc10299861f", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.071021056Z", "endTime": "2021-04-20T20:33:36.151107328Z", "durationInNanos": 80086272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "de9f05334009f30f"}}
+{ "traceId": "19b592faebd7e10a4824b919bcd3bd89", "spanId": "de9f05334009f30f", "traceState": "", "parentSpanId": "9e8cf0411a1b61f8", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.069997312Z", "endTime": "2021-04-20T20:33:36.166950656Z", "durationInNanos": 96953344, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60770, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7aa2821664832544"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "7aa2821664832544", "traceState": "", "parentSpanId": "bb004c0fd4fe0458", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.512588032Z", "endTime": "2021-04-20T20:33:36.513520384Z", "durationInNanos": 932352, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "b515153fd36d853a"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "b515153fd36d853a", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.489266944Z", "endTime": "2021-04-20T20:33:36.528014080Z", "durationInNanos": 38747136, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "41b5cf2346593387"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "41b5cf2346593387", "traceState": "", "parentSpanId": "9835a28e768c1334", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.533314304Z", "endTime": "2021-04-20T20:33:36.564330496Z", "durationInNanos": 31016192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58410, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "937fb8345b252adb"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "937fb8345b252adb", "traceState": "", "parentSpanId": "b5eb104616d427e5", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:36.614607616Z", "endTime": "2021-04-20T20:33:36.620131584Z", "durationInNanos": 5523968, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b5eb104616d427e5"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "b5eb104616d427e5", "traceState": "", "parentSpanId": "702b587891032394", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.488680960Z", "endTime": "2021-04-20T20:33:36.622967040Z", "durationInNanos": 134286080, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "702b587891032394"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "702b587891032394", "traceState": "", "parentSpanId": "375cb3ef27c46997", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.487866112Z", "endTime": "2021-04-20T20:33:36.625204992Z", "durationInNanos": 137338880, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48158, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d3911d8b057539bb"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "d3911d8b057539bb", "traceState": "", "parentSpanId": "", "name": "client_checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:36.481575424Z", "endTime": "2021-04-20T20:33:36.650631936Z", "durationInNanos": 169056512, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_checkout", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "e71642d4deaf046a"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "e71642d4deaf046a", "traceState": "", "parentSpanId": "3d1fe27819634f95", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.024145664Z", "endTime": "2021-04-20T20:33:37.047470592Z", "durationInNanos": 23324928, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "c978b33c59a54196"}}
+{ "traceId": "ec830c13f81efb5082f6e40b4dedce71", "spanId": "c978b33c59a54196", "traceState": "", "parentSpanId": "a7fcdbe2bf6d6d75", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.062592256Z", "endTime": "2021-04-20T20:33:37.067854080Z", "durationInNanos": 5261824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a00565be802b54b4"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "a00565be802b54b4", "traceState": "", "parentSpanId": "dfbc0ecddf9324b7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.480550912Z", "endTime": "2021-04-20T20:33:37.481288960Z", "durationInNanos": 738048, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "67e273104da42d94"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "67e273104da42d94", "traceState": "", "parentSpanId": "e1f71dfda83b894c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.527881984Z", "endTime": "2021-04-20T20:33:37.528583168Z", "durationInNanos": 701184, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO User_Carts (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "965c5d8b0b6276c0"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "965c5d8b0b6276c0", "traceState": "", "parentSpanId": "67a615bb3d2aef86", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.500228096Z", "endTime": "2021-04-20T20:33:37.541810176Z", "durationInNanos": 41582080, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "6bf6fc5237230c42"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "6bf6fc5237230c42", "traceState": "", "parentSpanId": "1eda1c86b53778f8", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:37.404817152Z", "endTime": "2021-04-20T20:33:37.554722304Z", "durationInNanos": 149905152, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60812, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "91921c51d51c884f"}}
+{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "91921c51d51c884f", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.806868480Z", "endTime": "2021-04-20T20:33:37.807457792Z", "durationInNanos": 589312, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "8aa7fc60f5c7d6b9"}}
+{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "8aa7fc60f5c7d6b9", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.810970624Z", "endTime": "2021-04-20T20:33:37.811611392Z", "durationInNanos": 640768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "6e1dcac7d59fac91"}}
+{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "6e1dcac7d59fac91", "traceState": "", "parentSpanId": "fa65816f2428a950", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.823713280Z", "endTime": "2021-04-20T20:33:37.843032832Z", "durationInNanos": 19319552, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "921202e7eca9c5be"}}
+{ "traceId": "c9f83a98e8f1826c3a822eeb7b85a9d6", "spanId": "921202e7eca9c5be", "traceState": "", "parentSpanId": "3b8fd25db26f6336", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:37.784199936Z", "endTime": "2021-04-20T20:33:37.854919424Z", "durationInNanos": 70719488, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d65f4119e3d35c6f"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "d65f4119e3d35c6f", "traceState": "", "parentSpanId": "b8440d5b592650f2", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.157860352Z", "endTime": "2021-04-20T20:33:38.185885952Z", "durationInNanos": 28025600, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1b26c8058d3cd7b6"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "1b26c8058d3cd7b6", "traceState": "", "parentSpanId": "2fa45786a2e85af4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.238149632Z", "endTime": "2021-04-20T20:33:38.277396480Z", "durationInNanos": 39246848, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "952b9f3e06ee5533"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "952b9f3e06ee5533", "traceState": "", "parentSpanId": "45ff7de69dace1d6", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.153484288Z", "endTime": "2021-04-20T20:33:38.292515584Z", "durationInNanos": 139031296, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48218, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "45ff7de69dace1d6"}}
+{ "traceId": "22bdfd493901782340e7eea9e077acb9", "spanId": "45ff7de69dace1d6", "traceState": "", "parentSpanId": "67c3240b15bfc41a", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.151339520Z", "endTime": "2021-04-20T20:33:38.297237504Z", "durationInNanos": 145897984, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "03699d100410017f"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "03699d100410017f", "traceState": "", "parentSpanId": "e65cbb55e80306bb", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.578456320Z", "endTime": "2021-04-20T20:33:38.605642496Z", "durationInNanos": 27186176, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "7d1c23fc87c00b35"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "7d1c23fc87c00b35", "traceState": "", "parentSpanId": "d3449d96433ef65b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:38.641069568Z", "endTime": "2021-04-20T20:33:38.641892096Z", "durationInNanos": 822528, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "07b4d48cb660e9cc"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "07b4d48cb660e9cc", "traceState": "", "parentSpanId": "bde992160f31f631", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.556106240Z", "endTime": "2021-04-20T20:33:38.737072384Z", "durationInNanos": 180966144, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59740, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9aa1509f5e191508"}}
+{ "traceId": "509da2ddfc1a3d9fc88ed4b62f3cd079", "spanId": "9aa1509f5e191508", "traceState": "", "parentSpanId": "7b78d2bea411b2fe", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.359700428Z", "endTime": "2021-04-20T20:33:34.361556108Z", "durationInNanos": 1855680, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-4", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "e1dfd31ab1a2b193"}}
+{ "traceId": "c17023ed734d4daa5f97bb7972f0c935", "spanId": "e1dfd31ab1a2b193", "traceState": "", "parentSpanId": "7145d5e8e15acfb7", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:34.745707353Z", "endTime": "2021-04-20T20:33:34.747566050Z", "durationInNanos": 1858697, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "2751e720b71a60a4"}}
+{ "traceId": "1730cc8687cb4b504cd934560111d5a1", "spanId": "2751e720b71a60a4", "traceState": "", "parentSpanId": "31f5aad7d2ea1fcb", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:37.547512262Z", "endTime": "2021-04-20T20:33:37.548630086Z", "durationInNanos": 1117824, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "4b7e5e41b0e7fd04"}}
+{ "traceId": "7df67f7205abe19319bad85babb04ca9", "spanId": "4b7e5e41b0e7fd04", "traceState": "", "parentSpanId": "d11da5c9c394bde8", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:35.802002385Z", "endTime": "2021-04-20T20:33:35.804283108Z", "durationInNanos": 2280723, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-10", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57628, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "74e54ea9fdbf735f"}}
+{ "traceId": "cb077f0c195ce825befded0fb71c76f1", "spanId": "74e54ea9fdbf735f", "traceState": "", "parentSpanId": "900fb4b6271869ab", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:36.635002138Z", "endTime": "2021-04-20T20:33:36.637319816Z", "durationInNanos": 2317678, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57660, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "75b7e359c49acf55"}}
+{ "traceId": "82c7cf3d3540450a3acc00c41b7a9562", "spanId": "75b7e359c49acf55", "traceState": "", "parentSpanId": "02d508caf899367c", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:38.562002009Z", "endTime": "2021-04-20T20:33:38.563741689Z", "durationInNanos": 1739680, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57730, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "e1300ec1802ecc3c"}}
+{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "e1300ec1802ecc3c", "traceState": "", "parentSpanId": "913de07418b7eed7", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.931558144Z", "endTime": "2021-04-20T20:33:38.984496640Z", "durationInNanos": 52938496, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "8c03b29267586319"}}
+{ "traceId": "b23c2f42f054fd2e3bd6602318e609ed", "spanId": "8c03b29267586319", "traceState": "", "parentSpanId": "a03543bce133747e", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:38.927511808Z", "endTime": "2021-04-20T20:33:39.006228736Z", "durationInNanos": 78716928, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "f5fe5f65731875d1"}}
+{ "traceId": "a371f923b4967cb722e563725cc2a91d", "spanId": "f5fe5f65731875d1", "traceState": "", "parentSpanId": "3ed24d73086e3a5c", "name": "cartSold", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.432419840Z", "endTime": "2021-04-20T20:33:39.482711808Z", "durationInNanos": 50291968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58524, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_sold", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_sold", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "3ed24d73086e3a5c"}}
+{ "traceId": "a371f923b4967cb722e563725cc2a91d", "spanId": "3ed24d73086e3a5c", "traceState": "", "parentSpanId": "e2ca5dbb18427bbc", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:39.430222336Z", "endTime": "2021-04-20T20:33:39.487606272Z", "durationInNanos": 57383936, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "8eafdbb08ef33fac"}}
+{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "8eafdbb08ef33fac", "traceState": "", "parentSpanId": "f69d6486408d5ceb", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:39.753607936Z", "endTime": "2021-04-20T20:33:39.778727168Z", "durationInNanos": 25119232, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "6f9b9156dc914a59"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "6f9b9156dc914a59", "traceState": "", "parentSpanId": "027e1f4686076d5e", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.251508736Z", "endTime": "2021-04-20T20:33:40.252164096Z", "durationInNanos": 655360, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "7052b8e18f95d355"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "7052b8e18f95d355", "traceState": "", "parentSpanId": "669d2b7892e6854c", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.291585280Z", "endTime": "2021-04-20T20:33:40.296150784Z", "durationInNanos": 4565504, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "9253cd2f27e55a6f"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "9253cd2f27e55a6f", "traceState": "", "parentSpanId": "517b250c6b019d50", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.227543040Z", "endTime": "2021-04-20T20:33:40.301341184Z", "durationInNanos": 73798144, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60920, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "517b250c6b019d50"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "517b250c6b019d50", "traceState": "", "parentSpanId": "883dff4473fb6cb2", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:40.225460992Z", "endTime": "2021-04-20T20:33:40.305951232Z", "durationInNanos": 80490240, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "883dff4473fb6cb2"}}
+{ "traceId": "10b1ec1196741c85609a43ce435cdece", "spanId": "883dff4473fb6cb2", "traceState": "", "parentSpanId": "", "name": "client_cancel_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:40.225210368Z", "endTime": "2021-04-20T20:33:40.308697600Z", "durationInNanos": 83487232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_cancel_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1bf5449206413fa6"}}
+{ "traceId": "56280de557e9fa891bb6289d2fd53c8d", "spanId": "1bf5449206413fa6", "traceState": "", "parentSpanId": "8ac46543c6308b05", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:40.794464Z", "endTime": "2021-04-20T20:33:40.866789376Z", "durationInNanos": 72325376, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60930, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a4ba523cda11d1d3"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "a4ba523cda11d1d3", "traceState": "", "parentSpanId": "d10b1e24cdce1630", "name": "pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.182262528Z", "endTime": "2021-04-20T20:33:41.253643520Z", "durationInNanos": 71380992, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1c5f7bbfcfc2fd9c"}}
+{ "traceId": "259a8226fae090c7dff75784fc8c7b17", "spanId": "1c5f7bbfcfc2fd9c", "traceState": "", "parentSpanId": "", "name": "client_pay_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.179067136Z", "endTime": "2021-04-20T20:33:41.262793216Z", "durationInNanos": 83726080, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_pay_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "83033b37b8934e4d"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "83033b37b8934e4d", "traceState": "", "parentSpanId": "74ac44c4e08e204b", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.646461440Z", "endTime": "2021-04-20T20:33:41.647615744Z", "durationInNanos": 1154304, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT * FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "6b60bf20aca25776"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "6b60bf20aca25776", "traceState": "", "parentSpanId": "7b17041367225c99", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.623079680Z", "endTime": "2021-04-20T20:33:41.659422720Z", "durationInNanos": 36343040, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b88a8903d68855ac"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "b88a8903d68855ac", "traceState": "", "parentSpanId": "7b17041367225c99", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:41.662379264Z", "endTime": "2021-04-20T20:33:41.667096576Z", "durationInNanos": 4717312, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7b17041367225c99"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "7b17041367225c99", "traceState": "", "parentSpanId": "1abf21fef72f18ff", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.622877440Z", "endTime": "2021-04-20T20:33:41.669995776Z", "durationInNanos": 47118336, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1e0ea651a120db7b"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "1e0ea651a120db7b", "traceState": "", "parentSpanId": "46c91104e47a2a43", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.501964032Z", "endTime": "2021-04-20T20:33:42.533108224Z", "durationInNanos": 31144192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58598, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "46c91104e47a2a43"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "46c91104e47a2a43", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.499654144Z", "endTime": "2021-04-20T20:33:42.538212352Z", "durationInNanos": 38558208, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b1622ef608acbe07"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "b1622ef608acbe07", "traceState": "", "parentSpanId": "0c5d67b81c5daaa1", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.564037120Z", "endTime": "2021-04-20T20:33:42.564826880Z", "durationInNanos": 789760, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "48ab22a6aa9ead3d"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "48ab22a6aa9ead3d", "traceState": "", "parentSpanId": "0791aa225a461844", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.581447424Z", "endTime": "2021-04-20T20:33:42.620536064Z", "durationInNanos": 39088640, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "0791aa225a461844"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "0791aa225a461844", "traceState": "", "parentSpanId": "dd10a56f977e819c", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.499253760Z", "endTime": "2021-04-20T20:33:42.631327232Z", "durationInNanos": 132073472, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "dd10a56f977e819c"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "dd10a56f977e819c", "traceState": "", "parentSpanId": "868f60191f3524c9", "name": "update_inventory", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.498470144Z", "endTime": "2021-04-20T20:33:42.633447680Z", "durationInNanos": 134977536, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8082, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 48350, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_inventory", "span.attributes.http@host": "localhost:8082", "span.attributes.http@target": "/update_inventory", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "3121ff83a994e9da"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "3121ff83a994e9da", "traceState": "", "parentSpanId": "007459ff1ddd5dfb", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:42.640867584Z", "endTime": "2021-04-20T20:33:42.645658112Z", "durationInNanos": 4790528, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "007459ff1ddd5dfb"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "007459ff1ddd5dfb", "traceState": "", "parentSpanId": "4eaffcf10b0ddc1b", "name": "checkout", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:42.495881472Z", "endTime": "2021-04-20T20:33:42.649110784Z", "durationInNanos": 153229312, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "11538c0100bd4160"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "11538c0100bd4160", "traceState": "", "parentSpanId": "a0bed7d434593b60", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.451381504Z", "endTime": "2021-04-20T20:33:43.455993600Z", "durationInNanos": 4612096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a0bed7d434593b60"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "a0bed7d434593b60", "traceState": "", "parentSpanId": "36695d818f9b4e9a", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.388621312Z", "endTime": "2021-04-20T20:33:43.458705664Z", "durationInNanos": 70084352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "5268497625ace4e0"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "5268497625ace4e0", "traceState": "", "parentSpanId": "5e7bc4f9aae01a8f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:43.385700864Z", "endTime": "2021-04-20T20:33:43.466258432Z", "durationInNanos": 80557568, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e272f67b8738c361"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "e272f67b8738c361", "traceState": "", "parentSpanId": "f9e3a2177bd81a72", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.825311744Z", "endTime": "2021-04-20T20:33:43.878611712Z", "durationInNanos": 53299968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58628, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c173a5ab72d12cca"}}
+{ "traceId": "5bf7f62e1215df5526664ec45dd9ad63", "spanId": "c173a5ab72d12cca", "traceState": "", "parentSpanId": "4dc028a0167c3cf2", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:41.664562550Z", "endTime": "2021-04-20T20:33:41.665701036Z", "durationInNanos": 1138486, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "1d6646d320f46f92"}}
+{ "traceId": "1ca5c1d52ca730f16872553cde6933c0", "spanId": "1d6646d320f46f92", "traceState": "", "parentSpanId": "7d14b353b41504e2", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:43.888482916Z", "endTime": "2021-04-20T20:33:43.889715232Z", "durationInNanos": 1232316, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-6", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "cf2a67c23dc23bab"}}
+{ "traceId": "17af7b8dee49e8258b8b5ab82dd0235a", "spanId": "cf2a67c23dc23bab", "traceState": "", "parentSpanId": "652bc8d3182b25df", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:39.791001724Z", "endTime": "2021-04-20T20:33:39.792709638Z", "durationInNanos": 1707914, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57778, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "f405f62e61d4181f"}}
+{ "traceId": "52190817d7eb1b6d71e66cc9b0b14124", "spanId": "f405f62e61d4181f", "traceState": "", "parentSpanId": "3121ff83a994e9da", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:42.643002265Z", "endTime": "2021-04-20T20:33:42.644751821Z", "durationInNanos": 1749556, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-3", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 133, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57852, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "87af24ccbde5bc6b"}}
+{ "traceId": "c5eabf09201ab4df116e1881d0756035", "spanId": "87af24ccbde5bc6b", "traceState": "", "parentSpanId": "11538c0100bd4160", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:43.453001888Z", "endTime": "2021-04-20T20:33:43.454676059Z", "durationInNanos": 1674171, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57862, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "4a2d7a09233223ec"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "4a2d7a09233223ec", "traceState": "", "parentSpanId": "570073e77e68be9d", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.206169856Z", "endTime": "2021-04-20T20:33:44.206994688Z", "durationInNanos": 824832, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "c1ae726e0fb621b3"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "c1ae726e0fb621b3", "traceState": "", "parentSpanId": "24d81987a47f33dc", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.252928256Z", "endTime": "2021-04-20T20:33:44.253720576Z", "durationInNanos": 792320, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': '3'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "d87a0a46511625fb"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "d87a0a46511625fb", "traceState": "", "parentSpanId": "7696d367503845f7", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.232229376Z", "endTime": "2021-04-20T20:33:44.266917888Z", "durationInNanos": 34688512, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58642, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7696d367503845f7"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "7696d367503845f7", "traceState": "", "parentSpanId": "885e54cf2034b9f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.229940992Z", "endTime": "2021-04-20T20:33:44.272091648Z", "durationInNanos": 42150656, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "01b449260ce334f8"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "01b449260ce334f8", "traceState": "", "parentSpanId": "885e54cf2034b9f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.320410368Z", "endTime": "2021-04-20T20:33:44.324994048Z", "durationInNanos": 4583680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c85e5dec4106a06a"}}
+{ "traceId": "96db5f125cb54111f2a95d7419df8a15", "spanId": "c85e5dec4106a06a", "traceState": "", "parentSpanId": "0b957c5bc548b795", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.178796544Z", "endTime": "2021-04-20T20:33:44.335090176Z", "durationInNanos": 156293632, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "bd67ffd1aca8ebd9"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "bd67ffd1aca8ebd9", "traceState": "", "parentSpanId": "0ee38170cee8fb5c", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.555993344Z", "endTime": "2021-04-20T20:33:44.591705344Z", "durationInNanos": 35712000, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "0ee38170cee8fb5c"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "0ee38170cee8fb5c", "traceState": "", "parentSpanId": "afcb84a35556aad5", "name": "get_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:44.555788544Z", "endTime": "2021-04-20T20:33:44.602074368Z", "durationInNanos": 46285824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "afcb84a35556aad5"}}
+{ "traceId": "c0ef65e0d991727dbe26a071fd10e407", "spanId": "afcb84a35556aad5", "traceState": "", "parentSpanId": "e53a0ddf08ca7fe4", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:44.554990592Z", "endTime": "2021-04-20T20:33:44.604317184Z", "durationInNanos": 49326592, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32802, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "2131bd5f7b2bb426"}}
+{ "traceId": "70a3f615a998b76cd973d87710572913", "spanId": "2131bd5f7b2bb426", "traceState": "", "parentSpanId": "d6ed9d2f16247916", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:44.940555776Z", "endTime": "2021-04-20T20:33:45.019118848Z", "durationInNanos": 78563072, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/pay_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "83e66a83f1a293d1"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "83e66a83f1a293d1", "traceState": "", "parentSpanId": "5205b0912292faea", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.263542528Z", "endTime": "2021-04-20T20:33:45.287819520Z", "durationInNanos": 24276992, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "61e11870abc59f27"}}
+{ "traceId": "65e793c50b861f00c1534090639dd7c3", "spanId": "61e11870abc59f27", "traceState": "", "parentSpanId": "3cf94093fb7bea7c", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.260458752Z", "endTime": "2021-04-20T20:33:45.295847168Z", "durationInNanos": 35388416, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/get_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "80e3c195c1e1eb31"}}
+{ "traceId": "02feb3a4f611abd81f2a53244d1278ae", "spanId": "80e3c195c1e1eb31", "traceState": "", "parentSpanId": "9e64d04e62cd7e86", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.693580544Z", "endTime": "2021-04-20T20:33:45.694361344Z", "durationInNanos": 780800, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "3f748306070acb27"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "3f748306070acb27", "traceState": "", "parentSpanId": "69af53e3494bca1c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.937683456Z", "endTime": "2021-04-20T20:33:45.938361344Z", "durationInNanos": 677888, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "INSERT INTO Inventory_Items (ItemId, TotalQty) VALUES (%(ItemId)s, %(Qty)s) ON DUPLICATE KEY UPDATE TotalQty = TotalQty + %(Qty)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "3a025025e0a3b1fa"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "3a025025e0a3b1fa", "traceState": "", "parentSpanId": "093bfc1b96f299dd", "name": "cartEmpty", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.912724480Z", "endTime": "2021-04-20T20:33:45.971964416Z", "durationInNanos": 59239936, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "PUT", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58706, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/cart_empty", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/cart_empty", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "093bfc1b96f299dd"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "093bfc1b96f299dd", "traceState": "", "parentSpanId": "b5ad0d70c2c4c7d6", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:45.910498560Z", "endTime": "2021-04-20T20:33:45.977039104Z", "durationInNanos": 66540544, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b5ad0d70c2c4c7d6"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "b5ad0d70c2c4c7d6", "traceState": "", "parentSpanId": "04f5292ec03f47ff", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:45.910301952Z", "endTime": "2021-04-20T20:33:45.987429632Z", "durationInNanos": 77127680, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "1abb073eb56f2eea"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "1abb073eb56f2eea", "traceState": "", "parentSpanId": "b2c126fb125a3ec0", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.155314688Z", "endTime": "2021-04-20T20:33:46.180148224Z", "durationInNanos": 24833536, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:46.180106752Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "140b1c6e07ac7569"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "140b1c6e07ac7569", "traceState": "", "parentSpanId": "5edd047783ce31e6", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.197120Z", "endTime": "2021-04-20T20:33:46.223479808Z", "durationInNanos": 26359808, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:46.223439872Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "c220b54c4e5447d7"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "c220b54c4e5447d7", "traceState": "", "parentSpanId": "33c6e729ae31cf8e", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:46.147583744Z", "endTime": "2021-04-20T20:33:46.289920512Z", "durationInNanos": 142336768, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59968, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "33c6e729ae31cf8e"}}
+{ "traceId": "b450e7770b6bf942d91f238f77311fbe", "spanId": "33c6e729ae31cf8e", "traceState": "", "parentSpanId": "86582d579095a4b2", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.145408256Z", "endTime": "2021-04-20T20:33:46.294403840Z", "durationInNanos": 148995584, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "cfd7fff669823fd7"}}
+{ "traceId": "ba5a69d5dfd1eaa4077451d452ba473b", "spanId": "cfd7fff669823fd7", "traceState": "", "parentSpanId": "e270a32c23bb3d64", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.524823808Z", "endTime": "2021-04-20T20:33:46.526560Z", "durationInNanos": 1736192, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "3b2b065511029f95"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "3b2b065511029f95", "traceState": "", "parentSpanId": "759ba13f98ab3fc6", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.847089408Z", "endTime": "2021-04-20T20:33:46.871549696Z", "durationInNanos": 24460288, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "3f5318f871490765"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "3f5318f871490765", "traceState": "", "parentSpanId": "b2e9f99896086ca7", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:46.795104512Z", "endTime": "2021-04-20T20:33:46.936029952Z", "durationInNanos": 140925440, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "b2e9f99896086ca7"}}
+{ "traceId": "95b27b5462c0dccc7e08126a25e64d3f", "spanId": "b2e9f99896086ca7", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:46.794855168Z", "endTime": "2021-04-20T20:33:46.938890240Z", "durationInNanos": 144035072, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ad657e844f30d14a"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "ad657e844f30d14a", "traceState": "", "parentSpanId": "e0e2f20d2c1b7308", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.212077312Z", "endTime": "2021-04-20T20:33:47.212736768Z", "durationInNanos": 659456, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "8d4b7a48cb7ee8e9"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "8d4b7a48cb7ee8e9", "traceState": "", "parentSpanId": "f78dbd14cda8862e", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:47.231710720Z", "endTime": "2021-04-20T20:33:47.269911552Z", "durationInNanos": 38200832, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:47.269875456Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "6b10877e5ed07c99"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "6b10877e5ed07c99", "traceState": "", "parentSpanId": "c321930cea7a01b8", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.305689344Z", "endTime": "2021-04-20T20:33:47.306357248Z", "durationInNanos": 667904, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "c36ca0e19d93a20e"}}
+{ "traceId": "c0d5be4cfded4677b472caeb6dced6eb", "spanId": "c36ca0e19d93a20e", "traceState": "", "parentSpanId": "1e21d6eba3353211", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.185514752Z", "endTime": "2021-04-20T20:33:47.329954560Z", "durationInNanos": 144439808, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8082/update_inventory", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Update inventory response contains failed items.", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "385cdc02dfbd5f9c"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "385cdc02dfbd5f9c", "traceState": "", "parentSpanId": "b7db1195f7777f37", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:47.813824Z", "endTime": "2021-04-20T20:33:47.849940480Z", "durationInNanos": 36116480, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "728745836581a137"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "728745836581a137", "traceState": "", "parentSpanId": "f4fb15e340c39da3", "name": "get_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.096090880Z", "endTime": "2021-04-20T20:33:48.120184832Z", "durationInNanos": 24093952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "30bde1e6725bc066"}}
+{ "traceId": "ecfe3ff116a31b4c5ec107289b615ff3", "spanId": "30bde1e6725bc066", "traceState": "", "parentSpanId": "2a4047a9b194cba8", "name": "pay_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.387603456Z", "endTime": "2021-04-20T20:33:48.463539712Z", "durationInNanos": 75936256, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32960, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/pay_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/pay_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f0839669f041b029"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "f0839669f041b029", "traceState": "", "parentSpanId": "8b858870f3946a12", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:48.727124224Z", "endTime": "2021-04-20T20:33:48.776144128Z", "durationInNanos": 49019904, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 32970, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "8b858870f3946a12"}}
+{ "traceId": "a7e35e333fe32a4fa0448bf258fff8e9", "spanId": "8b858870f3946a12", "traceState": "", "parentSpanId": "5d15d016d2efc520", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.725030144Z", "endTime": "2021-04-20T20:33:48.780702464Z", "durationInNanos": 55672320, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7ff60cf452880953"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "7ff60cf452880953", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.000432896Z", "endTime": "2021-04-20T20:33:49.036928768Z", "durationInNanos": 36495872, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "17ba287b7e0a55a5"}}
+{ "traceId": "2aa556a9a859155d7f578aacf259588f", "spanId": "17ba287b7e0a55a5", "traceState": "", "parentSpanId": "11f0fc7fd6fc8ef7", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.133449435Z", "endTime": "2021-04-20T20:33:48.134655277Z", "durationInNanos": 1205842, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "75432a4e251c77c6"}}
+{ "traceId": "97551ce4600c334d4ab8fb8725ac1e67", "spanId": "75432a4e251c77c6", "traceState": "", "parentSpanId": "3922ee10e2a02211", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:45.982001755Z", "endTime": "2021-04-20T20:33:45.983769151Z", "durationInNanos": 1767396, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 57950, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "934a3522bd05ed13"}}
+{ "traceId": "e48a85b3dc34426059aa1347ea4171a5", "spanId": "934a3522bd05ed13", "traceState": "", "parentSpanId": "ad97f94c920dd63a", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.484001785Z", "endTime": "2021-04-20T20:33:47.485831317Z", "durationInNanos": 1829532, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-4", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 134, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58022, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "ee28b3abcaca75b1"}}
+{ "traceId": "16f5176887289baa94c27f12604b5163", "spanId": "ee28b3abcaca75b1", "traceState": "", "parentSpanId": "4eeed8358a7d5d30", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:47.894001979Z", "endTime": "2021-04-20T20:33:47.895816736Z", "durationInNanos": 1814757, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58040, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "362c0d7748107d8f"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "362c0d7748107d8f", "traceState": "", "parentSpanId": "c6c238ba3d8255f4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.080640768Z", "endTime": "2021-04-20T20:33:49.120250368Z", "durationInNanos": 39609600, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "6de234553c12cdd0"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "6de234553c12cdd0", "traceState": "", "parentSpanId": "7559e66e65139dc8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:48.997068544Z", "endTime": "2021-04-20T20:33:49.137304320Z", "durationInNanos": 140235776, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7559e66e65139dc8"}}
+{ "traceId": "25af475f804ec5edbfab9d1ba4018ce5", "spanId": "7559e66e65139dc8", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:48.996784896Z", "endTime": "2021-04-20T20:33:49.140167168Z", "durationInNanos": 143382272, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "fd57eface760a3c2"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "fd57eface760a3c2", "traceState": "", "parentSpanId": "c4eb12c87b56bbaf", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.547070976Z", "endTime": "2021-04-20T20:33:49.547717376Z", "durationInNanos": 646400, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "797a61c1556157d8"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "797a61c1556157d8", "traceState": "", "parentSpanId": "5e65bb1294c655ad", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.586952448Z", "endTime": "2021-04-20T20:33:49.587582464Z", "durationInNanos": 630016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "5e65bb1294c655ad"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "5e65bb1294c655ad", "traceState": "", "parentSpanId": "4111fb00ec1efd77", "name": "update_item", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.567184128Z", "endTime": "2021-04-20T20:33:49.591741696Z", "durationInNanos": 24557568, "serviceName": "database", "events": [ { "time": "2021-04-20T20:33:49.591707904Z", "name": "exception", "attributes": { "exception@message": "", "exception@type": "InvalidItemUpdate", "exception@stacktrace": """Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/opentelemetry/sdk/trace/__init__.py", line 804, in use_span yield span File "databaseService.py", line 162, in updateItem raise InvalidItemUpdate("Not enough storage for itemId {}".format(data[ "ItemId" ])) InvalidItemUpdate """ }, "droppedAttributesCount": 0 } ], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "status.message": "InvalidItemUpdate: ", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 2, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "4111fb00ec1efd77"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "4111fb00ec1efd77", "traceState": "", "parentSpanId": "977b8ddb69c6d9a7", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:49.566329344Z", "endTime": "2021-04-20T20:33:49.596302592Z", "durationInNanos": 29973248, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58870, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "977b8ddb69c6d9a7"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "977b8ddb69c6d9a7", "traceState": "", "parentSpanId": "28991f1d3a174ce4", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.564026112Z", "endTime": "2021-04-20T20:33:49.601558016Z", "durationInNanos": 37531904, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/update_item", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "Not enough storage for itemId orange", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "704f4cab0d9b5606"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "704f4cab0d9b5606", "traceState": "", "parentSpanId": "bd73a71f8d9cc289", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.627682304Z", "endTime": "2021-04-20T20:33:49.628331008Z", "durationInNanos": 648704, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': 1}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "28991f1d3a174ce4"}}
+{ "traceId": "c1bd83b99e3992292daa0888489e618c", "spanId": "28991f1d3a174ce4", "traceState": "", "parentSpanId": "d0f5f8f6a9167a1c", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.523589632Z", "endTime": "2021-04-20T20:33:49.645100288Z", "durationInNanos": 121510656, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "79a8b5b769a8af40"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "79a8b5b769a8af40", "traceState": "", "parentSpanId": "cc39a5b2d98e4127", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:49.876797696Z", "endTime": "2021-04-20T20:33:49.896148736Z", "durationInNanos": 19351040, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "TRUNCATE TABLE User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "cc39a5b2d98e4127"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "cc39a5b2d98e4127", "traceState": "", "parentSpanId": "2c3fe2ecd7602e0b", "name": "cart_empty", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.851799296Z", "endTime": "2021-04-20T20:33:49.899272448Z", "durationInNanos": 47473152, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "de9f1128bf12b7b9"}}
+{ "traceId": "7a3182e62d533fa1e0617f21f5681a37", "spanId": "de9f1128bf12b7b9", "traceState": "", "parentSpanId": "1861602b0fed74c0", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:49.848355584Z", "endTime": "2021-04-20T20:33:49.917926400Z", "durationInNanos": 69570816, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "0d15e0e38cc75348"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "0d15e0e38cc75348", "traceState": "", "parentSpanId": "0b9642ed51dc4523", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.183780864Z", "endTime": "2021-04-20T20:33:50.208142848Z", "durationInNanos": 24361984, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "3b639def2d6ec40f"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "3b639def2d6ec40f", "traceState": "", "parentSpanId": "f53b324dd57c0a67", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.140426496Z", "endTime": "2021-04-20T20:33:50.269464320Z", "durationInNanos": 129037824, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33036, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f53b324dd57c0a67"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "f53b324dd57c0a67", "traceState": "", "parentSpanId": "0721e6662945f8c1", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.138248960Z", "endTime": "2021-04-20T20:33:50.274230272Z", "durationInNanos": 135981312, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/update_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "0721e6662945f8c1"}}
+{ "traceId": "247d610dcbd05da1c7902081b6bec1f6", "spanId": "0721e6662945f8c1", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.137996544Z", "endTime": "2021-04-20T20:33:50.276978688Z", "durationInNanos": 138982144, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "3a565f7129913c17"}}
+{ "traceId": "eef4554373e188267b38928e2dabeab4", "spanId": "3a565f7129913c17", "traceState": "", "parentSpanId": "59ff85f342e07d43", "name": "HTTP GET", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:50.475230464Z", "endTime": "2021-04-20T20:33:50.531948288Z", "durationInNanos": 56717824, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/get_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "GET", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "76d4028a33aa32d4"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "76d4028a33aa32d4", "traceState": "", "parentSpanId": "c80dc4c948d060d2", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.730701312Z", "endTime": "2021-04-20T20:33:50.759436800Z", "durationInNanos": 28735488, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58922, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "7e0f8516534902ba"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "7e0f8516534902ba", "traceState": "", "parentSpanId": "815628d64969d668", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:50.727141632Z", "endTime": "2021-04-20T20:33:50.855739904Z", "durationInNanos": 128598272, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "815628d64969d668"}}
+{ "traceId": "20eabd650f3a068d9f590786f56885e7", "spanId": "815628d64969d668", "traceState": "", "parentSpanId": "f16d32410e946012", "name": "update_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:50.725899008Z", "endTime": "2021-04-20T20:33:50.857993472Z", "durationInNanos": 132094464, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33066, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/update_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "06838c62d1f8fc52"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "06838c62d1f8fc52", "traceState": "", "parentSpanId": "", "name": "client_delivery_status", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.133010176Z", "endTime": "2021-04-20T20:33:51.191095040Z", "durationInNanos": 58084864, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_delivery_status", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "c2c0543fe0270e38"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "c2c0543fe0270e38", "traceState": "", "parentSpanId": "eb593b21c00b38c7", "name": "cart_sold", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.416972800Z", "endTime": "2021-04-20T20:33:51.463561472Z", "durationInNanos": 46588672, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "d9dd1b7eed5760a0"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "d9dd1b7eed5760a0", "traceState": "", "parentSpanId": "2b7af871bd8cd43f", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.413930240Z", "endTime": "2021-04-20T20:33:51.472114688Z", "durationInNanos": 58184448, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_sold", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "3301dd384d83dc66"}}
+{ "traceId": "7f63958e2172b12500e40eed557a31c7", "spanId": "3301dd384d83dc66", "traceState": "", "parentSpanId": "9de35fba7cb7c4a3", "name": "get_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.679142400Z", "endTime": "2021-04-20T20:33:51.729883904Z", "durationInNanos": 50741504, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "GET", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33104, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/get_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/get_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "c5e70373eb296aff"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "c5e70373eb296aff", "traceState": "", "parentSpanId": "49bf3ba4725523ca", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.977397248Z", "endTime": "2021-04-20T20:33:51.978067200Z", "durationInNanos": 669952, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "91b0beabefca51d0"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "91b0beabefca51d0", "traceState": "", "parentSpanId": "a7accb6ac082369d", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.956622336Z", "endTime": "2021-04-20T20:33:51.985689344Z", "durationInNanos": 29067008, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58970, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "a7accb6ac082369d"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "a7accb6ac082369d", "traceState": "", "parentSpanId": "6576e80159aee6b8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.954316288Z", "endTime": "2021-04-20T20:33:51.990446336Z", "durationInNanos": 36130048, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "439eff3f753e8e67"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "439eff3f753e8e67", "traceState": "", "parentSpanId": "6576e80159aee6b8", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:51.993564672Z", "endTime": "2021-04-20T20:33:52.029644544Z", "durationInNanos": 36079872, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "e0f5b0c6a6b1bbc2"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "e0f5b0c6a6b1bbc2", "traceState": "", "parentSpanId": "7b8507bd4a5a909f", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.055813888Z", "endTime": "2021-04-20T20:33:52.056485632Z", "durationInNanos": 671744, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': '2'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "ab4ac8bcf7351137"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "ab4ac8bcf7351137", "traceState": "", "parentSpanId": "1717b0bbc49c8b5c", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.034881024Z", "endTime": "2021-04-20T20:33:52.063697664Z", "durationInNanos": 28816640, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58978, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "0124ac48730385cc"}}
+{ "traceId": "340a6c6f70a21d1bc8456dbbe5c79929", "spanId": "0124ac48730385cc", "traceState": "", "parentSpanId": "", "name": "client_create_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:51.950673408Z", "endTime": "2021-04-20T20:33:52.088491264Z", "durationInNanos": 137817856, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": "client_create_order", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "e978fe4781c7212b"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "e978fe4781c7212b", "traceState": "", "parentSpanId": "f8aedbcbab807a78", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.270512128Z", "endTime": "2021-04-20T20:33:52.275296512Z", "durationInNanos": 4784384, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "0db04213ba31cb79"}}
+{ "traceId": "261f4f9f6d49c04588ddfc0b22d167c6", "spanId": "0db04213ba31cb79", "traceState": "", "parentSpanId": "66dd3959b912162c", "name": "HTTP DELETE", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.205003776Z", "endTime": "2021-04-20T20:33:52.284966144Z", "durationInNanos": 79962368, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8088/clear_order", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "DELETE", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f14b6b57d7079a58"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "f14b6b57d7079a58", "traceState": "", "parentSpanId": "9e4947190e28b8f7", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.520363008Z", "endTime": "2021-04-20T20:33:52.521067776Z", "durationInNanos": 704768, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'apple', 'Qty': '1'}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "2c37405ee8325196"}}
+{ "traceId": "5be8370207cbb002a165d369fbc57b57", "spanId": "2c37405ee8325196", "traceState": "", "parentSpanId": "702250f453a02be6", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.535895296Z", "endTime": "2021-04-20T20:33:52.571971584Z", "durationInNanos": 36076288, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/add_item_to_cart", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "14148032cdebd6e5"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "14148032cdebd6e5", "traceState": "", "parentSpanId": "d985b5239c10d8bf", "name": "add_item_to_cart", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.678805504Z", "endTime": "2021-04-20T20:33:52.703546112Z", "durationInNanos": 24740608, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "ec48acd974e4f4ef"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "ec48acd974e4f4ef", "traceState": "", "parentSpanId": "8873f17b55cf568a", "name": "addItemToCart", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:52.717049088Z", "endTime": "2021-04-20T20:33:52.745951744Z", "durationInNanos": 28902656, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59020, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/add_item_to_cart", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/add_item_to_cart", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "d85ef60c6b05ea1e"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "d85ef60c6b05ea1e", "traceState": "", "parentSpanId": "e0514a47c90c0ead", "name": "update_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.675259392Z", "endTime": "2021-04-20T20:33:52.823244288Z", "durationInNanos": 147984896, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "a9ae73162186cc7f"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "a9ae73162186cc7f", "traceState": "", "parentSpanId": "ff285f4458209cf3", "name": "HTTP PUT", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.927145216Z", "endTime": "2021-04-20T20:33:52.990285312Z", "durationInNanos": 63140096, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8083/cart_empty", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "PUT", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "477408f3368f28af"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "477408f3368f28af", "traceState": "", "parentSpanId": "ff285f4458209cf3", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:52.993329920Z", "endTime": "2021-04-20T20:33:52.997798144Z", "durationInNanos": 4468224, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8087/logs", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "f45a94f980605697"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "f45a94f980605697", "traceState": "", "parentSpanId": "470ef7b1b1e8c06c", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.238649856Z", "endTime": "2021-04-20T20:33:53.239367680Z", "durationInNanos": 717824, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'banana', 'Qty': 2}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "c07900555826d95f"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "c07900555826d95f", "traceState": "", "parentSpanId": "68f6536a0523f7f3", "name": "updateItem", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.217669120Z", "endTime": "2021-04-20T20:33:53.248192768Z", "durationInNanos": 30523648, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8083, "span.attributes.http@status_text": "Not enough storage for itemId banana", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "http", "status.code": 2, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 59046, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/update_item", "span.attributes.http@host": "localhost:8083", "span.attributes.http@target": "/update_item", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 422 }
+{ "index":{"_id": "854e04d060d378a8"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "854e04d060d378a8", "traceState": "", "parentSpanId": "a4030e9ad85b2a92", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.279769344Z", "endTime": "2021-04-20T20:33:53.280431360Z", "durationInNanos": 662016, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.db@statement@parameters": "{'ItemId': 'orange', 'Qty': 3}", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "UPDATE Inventory_Items SET TotalQty=IF(TotalQty >= %(Qty)s, TotalQty - %(Qty)s, TotalQty) WHERE ItemId=%(ItemId)s", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "2badcc8448bd5c5b"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "2badcc8448bd5c5b", "traceState": "", "parentSpanId": "6dcb9bfdeb68bef1", "name": "update_inventory", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.214871808Z", "endTime": "2021-04-20T20:33:53.338653184Z", "durationInNanos": 123781376, "serviceName": "inventory", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140491849416656", "resource.attributes.service@name": "inventory", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "79e7e8f4a6b9cfd6"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "79e7e8f4a6b9cfd6", "traceState": "", "parentSpanId": "b52867ccd766e67b", "name": "payment", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.210643200Z", "endTime": "2021-04-20T20:33:53.350407680Z", "durationInNanos": 139764480, "serviceName": "payment", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8084, "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "139782029922256", "resource.attributes.service@name": "payment", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 60296, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/checkout", "span.attributes.http@host": "localhost:8084", "span.attributes.http@target": "/checkout", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "b52867ccd766e67b"}}
+{ "traceId": "0bda4f69a15675f56069fa7b677f1c74", "spanId": "b52867ccd766e67b", "traceState": "", "parentSpanId": "4c7ff265c1e0c9dc", "name": "HTTP POST", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.208381952Z", "endTime": "2021-04-20T20:33:53.354845184Z", "durationInNanos": 146463232, "serviceName": "frontend-client", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.http@url": "http://localhost:8084/checkout", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.http@status_text": "PARTIAL CONTENT", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@name": "frontend-client", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.requests", "span.attributes.http@method": "POST", "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@status_code": 206 }
+{ "index":{"_id": "7745e3605083e150"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "7745e3605083e150", "traceState": "", "parentSpanId": "f6b9b0130d0a7765", "name": "mysql.APM", "kind": "SPAN_KIND_CLIENT", "startTime": "2021-04-20T20:33:53.454045184Z", "endTime": "2021-04-20T20:33:53.455569152Z", "durationInNanos": 1523968, "serviceName": "database", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.db@user": "root", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.net@peer@name": "localhost", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140009019686864", "resource.attributes.service@name": "database", "span.attributes.component": "mysql", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.mysql", "span.attributes.db@type": "sql", "span.attributes.net@peer@port": 3306, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.db@instance": "APM", "span.attributes.db@statement": "SELECT ItemId, TotalQty FROM User_Carts", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal" }
+{ "index":{"_id": "cefea796ccf54813"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "cefea796ccf54813", "traceState": "", "parentSpanId": "28b54e1dd64fcf7d", "name": "clear_order", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:53.429565696Z", "endTime": "2021-04-20T20:33:53.503151872Z", "durationInNanos": 73586176, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@sdk@language": "python", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "status.code": 0, "instrumentationLibrary.name": "__main__" }
+{ "index":{"_id": "28b54e1dd64fcf7d"}}
+{ "traceId": "d5bc99166e521eec173bcb7f9b0d3c43", "spanId": "28b54e1dd64fcf7d", "traceState": "", "parentSpanId": "1dc7b46c2357c388", "name": "clear_order", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:53.428727808Z", "endTime": "2021-04-20T20:33:53.505276160Z", "durationInNanos": 76548352, "serviceName": "order", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "instrumentationLibrary.version": "0.14b0", "resource.attributes.telemetry@sdk@language": "python", "span.attributes.host@port": 8088, "span.attributes.http@status_text": "OK", "resource.attributes.telemetry@sdk@version": "0.14b0", "resource.attributes.service@instance@id": "140034008389000", "resource.attributes.service@name": "order", "span.attributes.component": "http", "status.code": 0, "instrumentationLibrary.name": "opentelemetry.instrumentation.flask", "span.attributes.http@method": "DELETE", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 33208, "resource.attributes.telemetry@sdk@name": "opentelemetry", "span.attributes.http@server_name": "0.0.0.0", "span.attributes.http@route": "/clear_order", "span.attributes.http@host": "localhost:8088", "span.attributes.http@target": "/clear_order", "span.attributes.http@scheme": "http", "resource.attributes.host@hostname": "ip-172-31-68-90.ec2.internal", "span.attributes.http@flavor": "1.1", "span.attributes.http@status_code": 200 }
+{ "index":{"_id": "fc1d1ffce95a27aa"}}
+{ "traceId": "4216a647a4396e50fc12cc78d571557e", "spanId": "fc1d1ffce95a27aa", "traceState": "", "parentSpanId": "0f929cd09feb717a", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.818457432Z", "endTime": "2021-04-20T20:33:52.819488855Z", "durationInNanos": 1031423, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-8", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "f44426165fbba4d0"}}
+{ "traceId": "e447ed617aa651a7593c720d7e976625", "spanId": "f44426165fbba4d0", "traceState": "", "parentSpanId": "b272143e732a91e9", "name": "LoggingController.save", "kind": "SPAN_KIND_INTERNAL", "startTime": "2021-04-20T20:33:52.995465166Z", "endTime": "2021-04-20T20:33:52.996460896Z", "durationInNanos": 995730, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.thread@name": "http-nio-8087-exec-10", "resource.attributes.telemetry@sdk@name": "opentelemetry", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 140, "resource.attributes.telemetry@auto@version": "0.10.1", "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.spring-webmvc" }
+{ "index":{"_id": "9fd37843dd616fab"}}
+{ "traceId": "c48260d3774d6c2d4ba77c9e813eadec", "spanId": "9fd37843dd616fab", "traceState": "", "parentSpanId": "3ed06551056e1fa6", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.176001692Z", "endTime": "2021-04-20T20:33:51.177560735Z", "durationInNanos": 1559043, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-6", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 136, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58184, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
+{ "index":{"_id": "fce44d7569908ba7"}}
+{ "traceId": "56127a0a4f362cfb605a907e6c419c6e", "spanId": "fce44d7569908ba7", "traceState": "", "parentSpanId": "608bd5e547e88e3e", "name": "/logs", "kind": "SPAN_KIND_SERVER", "startTime": "2021-04-20T20:33:51.477002352Z", "endTime": "2021-04-20T20:33:51.478943130Z", "durationInNanos": 1940778, "serviceName": "analytics-service", "events": [], "links": [], "droppedAttributesCount": 0, "droppedEventsCount": 0, "droppedLinksCount": 0, "traceGroup": null, "span.attributes.net@peer@ip": "127.0.0.1", "span.attributes.http@url": "http://localhost:8087/logs", "span.attributes.thread@name": "http-nio-8087-exec-8", "instrumentationLibrary.version": "0.10.1", "resource.attributes.telemetry@sdk@language": "java", "span.attributes.thread@id": 138, "resource.attributes.telemetry@sdk@version": "0.10.0", "resource.attributes.service@name": "analytics-service", "status.code": 0, "instrumentationLibrary.name": "io.opentelemetry.auto.servlet", "span.attributes.http@method": "POST", "span.attributes.http@user_agent": "python-requests/2.25.1", "span.attributes.net@peer@port": 58194, "resource.attributes.telemetry@sdk@name": "opentelemetry", "resource.attributes.telemetry@auto@version": "0.10.1", "span.attributes.http@flavor": "HTTP/1.1", "span.attributes.http@status_code": 200, "span.attributes.http@client_ip": "127.0.0.1" }
diff --git a/dashboards-observability/.cypress/utils/panel_constants.js b/dashboards-observability/.cypress/utils/panel_constants.js
new file mode 100644
index 000000000..987d1dc3c
--- /dev/null
+++ b/dashboards-observability/.cypress/utils/panel_constants.js
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const delay = 1300;
+
+export const TEST_PANEL = 'Test Panel';
+export const SAMPLE_PANEL = '[Logs] Web traffic Panel';
+
+export const SAMPLE_VISUALIZATIONS_NAMES = [
+ '[Logs] Average ram usage by operating systems',
+ '[Logs] Average ram usage per day by apple os',
+ '[Logs] Average ram usage per day by windows os',
+ '[Logs] Daily count for error response codes',
+ '[Logs] Count requests from US to CN, IN and JP',
+ '[Logs] Max and average bytes by host',
+ '[Logs] Count total requests by tags',
+ '[Logs] Daily average bytes',
+];
+
+export const PPL_VISUALIZATIONS = [
+ 'source = opensearch_dashboards_sample_data_flights | stats count() by Dest',
+ 'source = opensearch_dashboards_sample_data_flights | stats avg(FlightDelayMin) by Carrier',
+ 'source = opensearch_dashboards_sample_data_flights | stats max( DistanceKilometers ) by DestCityName',
+];
+
+export const PPL_VISUALIZATIONS_NAMES = [
+ 'Flight count by destination',
+ 'Average flight delay minutes',
+ 'Max distance by destination city',
+];
+
+export const NEW_VISUALIZATION_NAME = 'Flight count by destination airport';
+
+export const PPL_FILTER = "where Carrier = 'OpenSearch-Air' | where Dest = 'Munich Airport'";
diff --git a/dashboards-observability/.eslintrc.js b/dashboards-observability/.eslintrc.js
new file mode 100644
index 000000000..4d8297eb3
--- /dev/null
+++ b/dashboards-observability/.eslintrc.js
@@ -0,0 +1,14 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+module.exports = {
+ root: true,
+ extends: [
+ '@elastic/eslint-config-kibana',
+ 'plugin:@elastic/eui/recommended',
+ 'plugin:react-hooks/recommended',
+ ],
+};
+
diff --git a/.gitignore b/dashboards-observability/.gitignore
similarity index 100%
rename from .gitignore
rename to dashboards-observability/.gitignore
diff --git a/dashboards-observability/common/constants/application_analytics.ts b/dashboards-observability/common/constants/application_analytics.ts
new file mode 100644
index 000000000..df675a704
--- /dev/null
+++ b/dashboards-observability/common/constants/application_analytics.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const TAB_OVERVIEW_ID = 'app-analytics-overview';
+export const TAB_SERVICE_ID = 'app-analytics-service';
+export const TAB_TRACE_ID = 'app-analytics-trace';
+export const TAB_LOG_ID = 'app-analytics-log';
+export const TAB_PANEL_ID = 'app-analytics-panel';
+export const TAB_CONFIG_ID = 'app-analytics-config';
+export const TAB_OVERVIEW_TITLE = 'Overview';
+export const TAB_SERVICE_TITLE = 'Services';
+export const TAB_TRACE_TITLE = 'Traces & Spans';
+export const TAB_LOG_TITLE = 'Log Events';
+export const TAB_PANEL_TITLE = 'Panel';
+export const TAB_CONFIG_TITLE = 'Configuration';
+
+export const APP_ANALYTICS_API_PREFIX = '/api/observability/application';
diff --git a/dashboards-observability/common/constants/autocomplete.ts b/dashboards-observability/common/constants/autocomplete.ts
new file mode 100644
index 000000000..b8c1c41b9
--- /dev/null
+++ b/dashboards-observability/common/constants/autocomplete.ts
@@ -0,0 +1,202 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable prettier/prettier */
+
+import { BaseItem } from '@algolia/autocomplete-core';
+
+export const firstCommand = [{ label: 'source' }];
+
+export const pipeCommands = [
+ { label: 'dedup' },
+ { label: 'eval' },
+ { label: 'fields' },
+ { label: 'head' },
+ { label: 'parse' },
+ { label: 'rare' },
+ { label: 'rename' },
+ { label: 'sort' },
+ { label: 'stats' },
+ { label: 'top' },
+ { label: 'where' },
+];
+
+export const statsCommands = [
+ { label: 'count()' },
+ { label: 'sum(' },
+ { label: 'avg(' },
+ { label: 'max(' },
+ { label: 'min(' },
+ { label: 'var_samp(' },
+ { label: 'var_pop(' },
+ { label: 'stddev_samp(' },
+ { label: 'stddev_pop(' },
+];
+
+export const numberTypes = [
+ 'long',
+ 'integer',
+ 'short',
+ 'byte',
+ 'double',
+ 'float',
+ 'half_float',
+ 'scaled_float',
+ 'unsigned_long',
+];
+
+export interface AutocompleteItem extends BaseItem {
+ input: string;
+ itemName: string;
+ label: string;
+ suggestion: string;
+ __autocomplete_id?: number;
+}
+
+export interface FieldItem {
+ label: string;
+ type: string;
+}
+
+export interface IndexItem {
+ label: string;
+}
+
+export interface DataItem {
+ label: string;
+ doc_count: any;
+}
+
+const JUST_SEARCH_REGEX = /\s*(search\s+source|source|index)\s*=\s*[^\\\/\?\"\<\>\|\s\,\#]*(\s*,\s*[^\\\/\?\"\<\>\|\s\,\#]+)*/;
+const SEARCH_WHERE_REGEX = /\s*(search\s+source|source|index)\s*=\s*[^\\\/\?\"\<\>\|\s\,\#]*(\s*,\s*[^\\\/\?\"\<\>\|\s\,\#]+)*\s*\|\s*where\s+\S+\s*=\s*\S+/;
+const SEARCH_MATCH_REGEX = /\s*(search\s+source|source|index)\s*=\s*[^\\\/\?\"\<\>\|\s\,\#]*(\s*,\s*[^\\\/\?\"\<\>\|\s\,\#]+)*\s*\|\s*where\s+match\(\S+,\s*\S+\)/;
+export const EMPTY_REGEX = /^\s*\S*$/;
+export const FIELD_AFTER_COMMAND = /^\s*(dedup|eval|rare|top|rename|where\s+match\()\s+\S*$/;
+
+// Regex for where command
+export const MATCH_FIELD_AFTER_WHERE = /^\s*where\s+\S*$/;
+export const EQUAL_AFTER_WHERE_FIELD = /^\s*where\s+(\S+)\s+$/;
+export const DATA_AFTER_WHERE_EQUAL = /^\s*where\s+\S+\s*=\s*(("(\w|\s|')*)|(\d*\.?\d*)|\w*)$/;
+export const PIPE_AFTER_WHERE = /^\s*where\s+\S+\s*=\s*(("(\w|\s|')+")|(\d+\.?\d*)|\w+)\s+$/;
+export const COMMA_AFTER_FIELD = /^\s*where\s+match\(\s*([^\s,]+)\s*$/;
+export const DATA_AFTER_COMMA = /^\s*where\s+match\(\s*\S+\s*,\s*(("(\w|\s|')*)|(\d*\.?\d*)|\w*)$/;
+export const CLOSE_AFTER_DATA = /^\s*where\s+match\(\s*\S+\s*,\s*(("(\w|\s|')+")|(\d+\.?\d*)|\w+)\s+$/;
+export const PIPE_AFTER_MATCH = /^\s*where\s+match\(\s*\S+\s*,\s*(("(\w|\s|')+")|(\d+\.?\d*)|\w+)\s*\)\s*$/;
+
+// Regex for dedup command
+export const FIELD_IN_FIELD_LOOP = /^\s*dedup\s*\d*\s+\S+\s*(,\s*\S+\s*)*,\s*([^\s,]*)$/;
+export const COMMA_PIPE_AFTER_FIELD = /^\s*dedup\s*\d*\s+\S+\s*(,\s*\S+\s*)*\s+$/;
+export const PIPE_AFTER_KEEP_EMPTY = /^\s*dedup\s*\d*\s+\S+\s*(,\s*\S+\s*)*\s*keepempty=true\s+$/;
+export const PIPE_AFTER_CONSECUTIVE = /^\s*dedup\s*\d*\s+\S+\s*(,\s*\S+\s*)*\s*consecutive=true\s+$/;
+
+// Regex for eval command
+export const EQUAL_AFTER_EVAL_FIELD = /^\s*eval\s+(\S+)\s+$/;
+export const FIELD_AFTER_EVAL_EQUAL = /^\s*eval\s+\S+\s*=\s*\S*$/;
+export const MATH_AFTER_FIELD = /^\s*eval\s+\S+\s*=\s*\S+\s+$/;
+export const PIPE_MATH_AFTER_EXPRESSIONS = /^\s*eval\s+(\S+\s*=\s*\S+(\s*(\+|\-|\*|\/)\s*\S+)+)+\s+$/;
+
+// Regex for fields command
+export const PLUS_MINUS_FIELD_AFTER_FIELDS = /^\s*fields\s+\S*$/;
+export const FIELD_AFTER_PLUS_MINUS = /^\s*fields\s+(\+|\-)\s*\S*$/;
+export const COMMA_PIPE_AFTER_FIELDS = /^\s*fields\s+((\+|\-)\s+)?\S+\s*(,\s*\S+\s*)*\s+$/;
+export const FIELD_IN_FIELDS_LOOP = /^\s*fields\s+((\+|\-)\s+)?\S+\s*(,\s*\S+\s*)*,\s*\S*$/;
+
+// Regex for rare/top command
+export const COMMA_PIPE_BY_AFTER_FIELD = /^\s*(rare|top(\s+\d+)?)\s+\S+\s*(,\s*\S+\s*)*\s+\S*$/;
+export const RARE_TOP_FIELD_LOOP = /^\s*(rare|top(\s+\d+)?)\s+\S+\s*(,\s*\S+\s*)*,\s*\S*$/;
+export const FIELD_AFTER_BY = /^\s*(rare|top(\s+\d+)?)\s+\S+\s*(,\s*\S+\s*)*\s+by\s+\S*$/;
+export const PIPE_AFTER_GROUP_BY = /^\s*(rare|top(\s+\d+)?)\s+\S+\s*(,\s*\S+\s*)*\s+by\s+\S+\s+$/;
+
+// Regex for rename command
+export const AS_AFTER_FIELD = /^\s*rename\s+((,\s*)?\S+\s+as\s+\S+\s*)*\s*(,\s*)?\S+\s+\S*$/;
+export const COMMA_PIPE_AFTER_RENAME_FIELD = /^\s*rename\s+((,\s*)?\S+\s+as\s+\S+\s*)+$/;
+export const FIELD_AFTER_COMMA = /^\s*rename\s+((,\s*)?\S+\s+as\s+\S+\s*)+\s*,\s+\S*$/;
+
+// Regex for head command
+export const PIPE_AFTER_HEAD = /^\s*head\s+\d+\s+/;
+
+// Regex for sort command
+export const PLUS_MINUS_FIELD_AFTER_SORT = /^\s*sort(\s+\d+)?\s+\S*$/;
+export const FIELD_AFTER_PLUS_MINUS_SORT = /^\s*sort(\s+\d+)?((,\s*)?\s+(\+|\-)?\s*\S+\s*)*\s+(\+|\-)\s*\S*$/;
+export const COMMA_PIPE_AFTER_SORT_FIELD = /^\s*sort(\s+\d+)?((,\s*)?\s+(\+|\-)?\s*\S+\s*)*\s+\S+\s+$/;
+export const PLUS_MINUS_FIELD_IN_FIELDS_LOOP = /^\s*sort(\s+\d+)?((,\s*)?\s+(\+|\-)?\s*\S+\s*)*,\s+\S*$/;
+
+// Regex for stats command
+export const FIELD_SPAN_AFTER_GROUP_BY = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+by\s+\S*$/;
+export const NUM_FIELD_AFTER_AGGREGATION = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))*(,\s*)?(sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S*$/;
+export const FIELD_AFTER_SPAN = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+by\s+span\(\s*([^\s,]*)\s*$/;
+export const CLOSE_AFTER_SPAN = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+by\s+span\(\s*[^\s,]+\s*,\s*(("(\w|\s|')+")|(\d+\.?\d*)|\w+)\s+$/;
+export const PIPE_AFTER_SPAN = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+by\s+span\(\s*[^\s,]+\s*,\s*(("(\w|\s|')*")|(\d*\.?\d*)|\w*)\s*\)\s*$/;
+export const CLOSE_AFTER_FIELD = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))*(,\s*)?(sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s+$/;
+export const COMMA_PIPE_BY_AFTER_AGGREGATION = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+\S*$/;
+export const PIPE_AFTER_STATS_GROUP_BY = /^\s*stats\s+((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+by\s+\S+\s+$/;
+export const AGGREGATION_FOR_STATS= /^\s*stats\s+(((,\s*)?((sum|avg|max|min|var_samp|var_pop|stddev_samp|stddev_pop)\(\s*\S+\s*\)\s*)|((,\s*)?count\(\)\s*))+\s+,\s*)?\S*$/;
+
+// Regex for parse command
+export const STRING_FIELD_AFTER_PARSE = /^\s*parse\s+\S*$/;
+export const PIPE_AFTER_PARSE = /^\s*parse\s+\S+\s+$/;
+
+// Regex for source command
+export const EQUAL_AFTER_SOURCE = /^\s*source\s+$/;
+export const INDEX_AFTER_EQUAL = /^\s*source\s+=\s+[^\\\/\?\"\<\>\|\s\,\#]*$/;
+export const PIPE_COMMA_AFTER_INDEX = /^\s*source\s+=\s+[^\\\/\?\"\<\>\|\s\,\#]+(,[^\\\/\?\"\<\>\|\s\,\#]+)*\s+$/;
+export const MORE_INDEX_AFTER_COMMA = /^\s*source\s+=\s+[^\\\/\?\"\<\>\|\s\,\#]+(,[^\\\/\?\"\<\>\|\s\,\#]+)*,\s*[^\\\/\?\"\<\>\|\s\,\#]*\s*$/;
+
+export const regexForSuggestion = [
+ EMPTY_REGEX,
+ FIELD_AFTER_COMMAND,
+ MATCH_FIELD_AFTER_WHERE,
+ EQUAL_AFTER_WHERE_FIELD,
+ DATA_AFTER_WHERE_EQUAL,
+ PIPE_AFTER_WHERE,
+ COMMA_AFTER_FIELD,
+ DATA_AFTER_COMMA,
+ CLOSE_AFTER_DATA,
+ PIPE_AFTER_MATCH,
+ FIELD_IN_FIELD_LOOP,
+ COMMA_PIPE_AFTER_FIELD,
+ PIPE_AFTER_KEEP_EMPTY,
+ PIPE_AFTER_CONSECUTIVE,
+ EQUAL_AFTER_EVAL_FIELD,
+ FIELD_AFTER_EVAL_EQUAL,
+ MATH_AFTER_FIELD,
+ PIPE_MATH_AFTER_EXPRESSIONS,
+ PLUS_MINUS_FIELD_AFTER_FIELDS,
+ FIELD_AFTER_PLUS_MINUS,
+ COMMA_PIPE_AFTER_FIELDS,
+ FIELD_IN_FIELDS_LOOP,
+ COMMA_PIPE_BY_AFTER_FIELD,
+ RARE_TOP_FIELD_LOOP,
+ FIELD_AFTER_BY,
+ PIPE_AFTER_GROUP_BY,
+ COMMA_PIPE_AFTER_RENAME_FIELD,
+ FIELD_AFTER_COMMA,
+ AS_AFTER_FIELD,
+ PIPE_AFTER_HEAD,
+ PLUS_MINUS_FIELD_AFTER_SORT,
+ FIELD_AFTER_PLUS_MINUS_SORT,
+ PLUS_MINUS_FIELD_IN_FIELDS_LOOP,
+ COMMA_PIPE_AFTER_SORT_FIELD,
+ FIELD_SPAN_AFTER_GROUP_BY,
+ NUM_FIELD_AFTER_AGGREGATION,
+ FIELD_AFTER_SPAN,
+ CLOSE_AFTER_SPAN,
+ PIPE_AFTER_SPAN,
+ CLOSE_AFTER_FIELD,
+ COMMA_PIPE_BY_AFTER_AGGREGATION,
+ PIPE_AFTER_STATS_GROUP_BY,
+ AGGREGATION_FOR_STATS,
+ STRING_FIELD_AFTER_PARSE,
+ PIPE_AFTER_PARSE,
+ EQUAL_AFTER_SOURCE,
+ INDEX_AFTER_EQUAL,
+ PIPE_COMMA_AFTER_INDEX,
+ MORE_INDEX_AFTER_COMMA,
+];
+
+export const regexForIndex = [
+ JUST_SEARCH_REGEX,
+ SEARCH_WHERE_REGEX,
+ SEARCH_MATCH_REGEX,
+];
diff --git a/dashboards-observability/common/constants/custom_panels.ts b/dashboards-observability/common/constants/custom_panels.ts
new file mode 100644
index 000000000..0c02b97a2
--- /dev/null
+++ b/dashboards-observability/common/constants/custom_panels.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const CUSTOM_PANELS_API_PREFIX = '/api/observability/operational_panels';
+export const CUSTOM_PANELS_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/observability-plugin/operational-panels/';
+export const CREATE_PANEL_MESSAGE = 'Enter a name to describe the purpose of this custom panel.';
diff --git a/dashboards-observability/common/constants/explorer.ts b/dashboards-observability/common/constants/explorer.ts
new file mode 100644
index 000000000..fbe09f13b
--- /dev/null
+++ b/dashboards-observability/common/constants/explorer.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const EVENT_ANALYTICS_DOCUMENTATION_URL =
+ 'https://opensearch.org/docs/latest/observability-plugin/event-analytics/';
+export const OPEN_TELEMETRY_LOG_CORRELATION_LINK =
+ 'https://opentelemetry.io/docs/reference/specification/logs/overview/#log-correlation';
+export const RAW_QUERY = 'rawQuery';
+export const FINAL_QUERY = 'finalQuery';
+export const SELECTED_DATE_RANGE = 'selectedDateRange';
+export const INDEX = 'index';
+export const SELECTED_TIMESTAMP = 'selectedTimestamp';
+export const SELECTED_FIELDS = 'selectedFields';
+export const UNSELECTED_FIELDS = 'unselectedFields';
+export const AVAILABLE_FIELDS = 'availableFields';
+export const QUERIED_FIELDS = 'queriedFields';
+export const TAB_ID_TXT_PFX = 'query-panel-';
+export const TAB_TITLE = 'New query';
+export const TAB_CHART_TITLE = 'Visualizations';
+export const TAB_EVENT_TITLE = 'Events';
+export const TAB_EVENT_ID_TXT_PFX = 'main-content-events-';
+export const TAB_CHART_ID_TXT_PFX = 'main-content-vis-';
+export const TAB_EVENT_ID = 'main-content-events';
+export const TAB_CHART_ID = 'main-content-vis';
+export const HAS_SAVED_TIMESTAMP = 'hasSavedTimestamp';
+export const FILTER_OPTIONS = ['Visualization', 'Query'];
+export const SAVED_QUERY = 'savedQuery';
+export const SAVED_VISUALIZATION = 'savedVisualization';
+export const SAVED_OBJECT_ID = 'savedObjectId';
+export const SAVED_OBJECT_TYPE = 'objectType';
+export const TAB_CREATED_TYPE = 'tabCreatedType';
+export const NEW_TAB = 'newTab';
+export const REDIRECT_TAB = 'redirect_tab';
+export const PAGE_SIZE = 50;
+export const DEFAULT_COLUMNS = ['', 'Time', '_source'];
+export const OTEL_TRACE_ID = 'traceId';
+export const DATE_PICKER_FORMAT = 'YYYY-MM-DD HH:mm:ss';
+export const TIME_INTERVAL_OPTIONS = [
+ {
+ text: 'Minute',
+ value: 'm',
+ },
+ {
+ text: 'Hour',
+ value: 'h',
+ },
+ {
+ text: 'Day',
+ value: 'd',
+ },
+ {
+ text: 'Week',
+ value: 'w',
+ },
+ {
+ text: 'Month',
+ value: 'M',
+ },
+ {
+ text: 'Year',
+ value: 'y',
+ },
+];
+
+// redux
+export const SELECTED_QUERY_TAB = 'selectedQueryTab';
+export const QUERY_TAB_IDS = 'queryTabIds';
+export const NEW_SELECTED_QUERY_TAB = 'newSelectedQueryTab';
+export const REDUX_EXPL_SLICE_QUERIES = 'queries';
+export const REDUX_EXPL_SLICE_QUERY_RESULT = 'queryResults';
+export const REDUX_EXPL_SLICE_FIELDS = 'fields';
+export const REDUX_EXPL_SLICE_QUERY_TABS = 'queryTabs';
+export const REDUX_EXPL_SLICE_VISUALIZATION = 'explorerVisualization';
+export const REDUX_EXPL_SLICE_COUNT_DISTRIBUTION = 'countDistributionVisualization';
+export const PLOTLY_GAUGE_COLUMN_NUMBER = 5;
+export const APP_ANALYTICS_TAB_ID_REGEX = /application-analytics-tab.+/;
+export const DEFAULT_AVAILABILITY_QUERY = 'stats count() by span( timestamp, 1h )';
diff --git a/dashboards-observability/common/constants/notebooks.ts b/dashboards-observability/common/constants/notebooks.ts
new file mode 100644
index 000000000..c3140792c
--- /dev/null
+++ b/dashboards-observability/common/constants/notebooks.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const NOTEBOOKS_API_PREFIX = '/api/observability/notebooks';
+export const NOTEBOOKS_SELECTED_BACKEND = 'DEFAULT'; // ZEPPELIN || DEFAULT
+export const NOTEBOOKS_FETCH_SIZE = 1000;
+export const CREATE_NOTE_MESSAGE = 'Enter a name to describe the purpose of this notebook.';
+export const NOTEBOOKS_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/observability-plugin/notebooks/';
+
+export const zeppelinURL = 'http://localhost:8080';
+
+export const wreckOptions = {
+ baseUrl: zeppelinURL,
+ headers: { 'Content-Type': 'application/json' },
+};
+
+const BASE_NOTEBOOKS_URI = '/_plugins/_notebooks';
+export const OPENSEARCH_NOTEBOOKS_API = {
+ GET_NOTEBOOKS: `${BASE_NOTEBOOKS_URI}/notebooks`,
+ NOTEBOOK: `${BASE_NOTEBOOKS_URI}/notebook`,
+};
diff --git a/dashboards-observability/common/constants/shared.ts b/dashboards-observability/common/constants/shared.ts
new file mode 100644
index 000000000..19c0fb8fd
--- /dev/null
+++ b/dashboards-observability/common/constants/shared.ts
@@ -0,0 +1,127 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import CSS from 'csstype';
+
+// Client route
+export const PPL_BASE = '/api/ppl';
+export const PPL_SEARCH = '/search';
+export const DSL_BASE = '/api/dsl';
+export const DSL_SEARCH = '/search';
+export const DSL_CAT = '/cat.indices';
+export const DSL_MAPPING = '/indices.getFieldMapping';
+export const OBSERVABILITY_BASE = '/api/observability';
+export const EVENT_ANALYTICS = '/event_analytics';
+export const SAVED_OBJECTS = '/saved_objects';
+export const SAVED_QUERY = '/query';
+export const SAVED_VISUALIZATION = '/vis';
+
+// Server route
+export const PPL_ENDPOINT = '/_plugins/_ppl';
+export const SQL_ENDPOINT = '/_plugins/_sql';
+export const DSL_ENDPOINT = '/_plugins/_dsl';
+
+export const observabilityID = 'observability-dashboards';
+export const observabilityTitle = 'Observability';
+export const observabilityPluginOrder = 6000;
+
+// Shared Constants
+export const SQL_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/search-plugins/sql/index/';
+export const PPL_DOCUMENTATION_URL =
+ 'https://opensearch.org/docs/latest/observability-plugin/ppl/commands/';
+export const UI_DATE_FORMAT = 'MM/DD/YYYY hh:mm A';
+export const PPL_DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSSSSS';
+export const SPAN_REGEX = /span/;
+export const PPL_SPAN_REGEX = /by\s*span/i;
+export const PPL_STATS_REGEX = /\|\s*stats/i;
+export const PPL_INDEX_INSERT_POINT_REGEX = /(search source|source|index)\s*=\s*([^|\s]+)(.*)/i;
+export const PPL_INDEX_REGEX = /(search source|source|index)\s*=\s*([^|\s]+)/i;
+export const PPL_NEWLINE_REGEX = /[\n\r]+/g;
+
+// Observability plugin URI
+const BASE_OBSERVABILITY_URI = '/_plugins/_observability';
+export const OPENSEARCH_PANELS_API = {
+ OBJECT: `${BASE_OBSERVABILITY_URI}/object`,
+};
+
+// Saved Objects
+export const SAVED_OBJECT = '/object';
+
+// Color Constants
+export const PLOTLY_COLOR = [
+ '#3CA1C7',
+ '#8C55A3',
+ '#DB748A',
+ '#F2BE4B',
+ '#68CCC2',
+ '#2A7866',
+ '#843769',
+ '#374FB8',
+ '#BD6F26',
+ '#4C636F',
+];
+
+export const LONG_CHART_COLOR = PLOTLY_COLOR[1];
+
+export const pageStyles: CSS.Properties = {
+ float: 'left',
+ width: '100%',
+ maxWidth: '1130px',
+};
+
+export const NUMERICAL_FIELDS = ['short', 'integer', 'long', 'float', 'double'];
+
+export const ENABLED_VIS_TYPES = ['bar', 'horizontal_bar', 'line', 'pie', 'heatmap', 'text'];
+
+//Live tail constants
+export const LIVE_OPTIONS = [
+ {
+ label:'5s',
+ startTime: 'now-5s',
+ delayTime: 5000,
+ },
+ {
+ label:'10s',
+ startTime: 'now-10s',
+ delayTime: 10000,
+ },
+ {
+ label:'30s',
+ startTime: 'now-30s',
+ delayTime: 30000,
+ },
+ {
+ label:'1m',
+ startTime: 'now-1m',
+ delayTime: 60000,
+ },
+ {
+ label:'5m',
+ startTime: 'now-5m',
+ delayTime: 60000 * 5,
+ },
+ {
+ label:'15m',
+ startTime: 'now-15m',
+ delayTime: 60000 * 15,
+ },
+ {
+ label:'30m',
+ startTime: 'now-30m',
+ delayTime: 60000 * 30,
+ },
+ {
+ label:'1h',
+ startTime: 'now-1h',
+ delayTime: 60000 * 60,
+ },
+ {
+ label:'2h',
+ startTime: 'now-2h',
+ delayTime: 60000 * 120,
+ },
+];
+
+export const LIVE_END_TIME ='now';
\ No newline at end of file
diff --git a/dashboards-observability/common/constants/trace_analytics.ts b/dashboards-observability/common/constants/trace_analytics.ts
new file mode 100644
index 000000000..f480a25f6
--- /dev/null
+++ b/dashboards-observability/common/constants/trace_analytics.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const DATA_PREPPER_INDEX_NAME = 'otel-v1-apm-span-*';
+export const DATA_PREPPER_SERVICE_INDEX_NAME = 'otel-v1-apm-service-map*';
+export const TRACE_ANALYTICS_DATE_FORMAT = 'MM/DD/YYYY HH:mm:ss';
+export const TRACE_ANALYTICS_PLOTS_DATE_FORMAT = 'MMM D, YYYY HH:mm:ss';
+export const SERVICE_MAP_MAX_NODES = 500;
+// size limit when requesting edge related queries, not necessarily the number of edges
+export const SERVICE_MAP_MAX_EDGES = 1000;
+export const TRACES_MAX_NUM = 3000;
+export const TRACE_ANALYTICS_DOCUMENTATION_LINK = 'https://opensearch.org/docs/latest/observability-plugin/trace/index/';
+
+export const TRACE_ANALYTICS_INDICES_ROUTE = '/api/observability/trace_analytics/indices';
+export const TRACE_ANALYTICS_DSL_ROUTE = '/api/observability/trace_analytics/query';
diff --git a/dashboards-observability/common/types/application_analytics.ts b/dashboards-observability/common/types/application_analytics.ts
new file mode 100644
index 000000000..11f42c236
--- /dev/null
+++ b/dashboards-observability/common/types/application_analytics.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export interface OptionType {
+ label: string;
+}
+
+export interface ApplicationType {
+ id: string;
+ dateCreated: string;
+ dateModified: string;
+ name: string;
+ description: string;
+ baseQuery: string;
+ servicesEntities: string[];
+ traceGroups: string[];
+ panelId: string;
+ availability: { name: string; color: string; availabilityVisId: string };
+}
+
+export interface ApplicationRequestType {
+ name: string;
+ description: string;
+ baseQuery: string;
+ servicesEntities: string[];
+ traceGroups: string[];
+ panelId: string;
+ availabilityVisId: string;
+}
+
+export interface AvailabilityType {
+ name: string;
+ color: string;
+ availabilityVisId: string;
+}
diff --git a/dashboards-observability/common/types/custom_panels.ts b/dashboards-observability/common/types/custom_panels.ts
new file mode 100644
index 000000000..e397b0607
--- /dev/null
+++ b/dashboards-observability/common/types/custom_panels.ts
@@ -0,0 +1,47 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export interface CustomPanelListType {
+ name: string;
+ id: string;
+ dateCreated: number;
+ dateModified: number;
+ applicationId?: string;
+}
+
+export interface VisualizationType {
+ id: string;
+ savedVisualizationId: string;
+ x: number;
+ y: number;
+ w: number;
+ h: number;
+}
+
+export interface PanelType {
+ name: string;
+ visualizations: VisualizationType[];
+ timeRange: { to: string; from: string };
+ queryFilter: { query: string; language: string };
+ applicationId?: string;
+}
+
+export interface SavedVisualizationType {
+ id: string;
+ name: string;
+ query: string;
+ type: string;
+ selected_date_range: { start: string; end: string; text: string };
+ timeField: string;
+ application_id?: string;
+ user_configs: any;
+}
+
+export interface pplResponse {
+ data: any;
+ metadata: any;
+ size: number;
+ status: number;
+}
diff --git a/dashboards-observability/common/types/explorer.ts b/dashboards-observability/common/types/explorer.ts
new file mode 100644
index 000000000..d43aba751
--- /dev/null
+++ b/dashboards-observability/common/types/explorer.ts
@@ -0,0 +1,229 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { History } from 'history';
+import Plotly from 'plotly.js-dist';
+import {
+ RAW_QUERY,
+ SELECTED_FIELDS,
+ UNSELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ QUERIED_FIELDS,
+ INDEX,
+ FINAL_QUERY,
+ SELECTED_TIMESTAMP,
+ SELECTED_DATE_RANGE,
+} from '../constants/explorer';
+import { CoreStart, HttpStart, NotificationsStart } from '../../../../src/core/public';
+import SavedObjects from '../../public/services/saved_objects/event_analytics/saved_objects';
+import TimestampUtils from '../../public/services/timestamp/timestamp';
+import PPLService from '../../public/services/requests/ppl';
+import DSLService from '../../public/services/requests/dsl';
+
+export interface IQueryTab {
+ id: string;
+ name: React.ReactNode | string;
+ content: React.ReactNode;
+}
+
+export interface IField {
+ name: string;
+ type: string;
+}
+
+export interface ITabQueryResults {
+ [tabId: string]: any;
+}
+
+export interface ITabQueries {
+ [tabId: string]: IQuery;
+}
+
+export interface IQuery {
+ [RAW_QUERY]: string;
+ [FINAL_QUERY]: string;
+ [INDEX]: string;
+ [SELECTED_DATE_RANGE]: string[];
+ [SELECTED_TIMESTAMP]: string;
+}
+
+export interface IExplorerTabFields {
+ [tabId: string]: IExplorerFields;
+}
+
+export interface IExplorerFields {
+ [SELECTED_FIELDS]: IField[];
+ [UNSELECTED_FIELDS]: IField[];
+ [AVAILABLE_FIELDS]: IField[];
+ [QUERIED_FIELDS]: IField[];
+}
+
+export interface EmptyTabParams {
+ tabIds: string[] | undefined;
+ queries: any | undefined;
+ explorerData: any | undefined;
+}
+
+export interface ILogExplorerProps {
+ pplService: PPLService;
+ dslService: DSLService;
+ savedObjects: SavedObjects;
+ http: HttpStart;
+ history: History;
+ notifications: NotificationsStart;
+ timestampUtils: TimestampUtils;
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void;
+ savedObjectId: string;
+ getExistingEmptyTab: (params: EmptyTabParams) => string;
+}
+
+export interface IExplorerProps {
+ pplService: PPLService;
+ dslService: DSLService;
+ tabId: string;
+ savedObjects: SavedObjects;
+ timestampUtils: TimestampUtils;
+ history: History;
+ notifications: NotificationsStart;
+ savedObjectId: string;
+ curSelectedTabId: React.MutableRefObject;
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void;
+ http: CoreStart['http'];
+ tabCreatedTypes?: any;
+ searchBarConfigs?: any;
+ appId?: string;
+ addVisualizationToPanel?: any;
+ startTime?: string;
+ endTime?: string;
+ setStartTime?: any;
+ setEndTime?: any;
+ appBaseQuery?: string;
+ callback?: any;
+ callbackInApp?: any;
+}
+
+export interface SavedQuery {
+ description: string;
+ name: string;
+ query: string;
+ selected_date_range: { start: string; end: string; text: string };
+ selected_fields: { text: string; tokens: [{ name: string; type: string }] };
+ selected_timestamp: { name: string; type: string };
+}
+
+export interface SavedVisualization {
+ description: string;
+ name: string;
+ query: string;
+ selected_date_range: { start: string; end: string; text: string };
+ selected_fields: { text: string; tokens: [] };
+ selected_timestamp: { name: string; type: string };
+ type: string;
+ application_id?: string;
+}
+
+export interface SavedQueryRes {
+ createdTimeMs: number;
+ lastUpdatedTimeMs: number;
+ objectId: string;
+ savedQuery: SavedQuery;
+ tenant: string;
+}
+
+export interface SavedVizRes {
+ createdTimeMs: number;
+ lastUpdatedTimeMs: number;
+ objectId: string;
+ savedVisualization: SavedVisualization;
+ tenant: string;
+}
+
+export interface IVisualizationContainerPropsData {
+ appData?: { fromApp: boolean };
+ rawVizData?: any;
+ query?: IQuery;
+ indexFields?: IField[];
+ userConfigs?: any;
+ defaultAxes?: {
+ xaxis: IField[];
+ yaxis: IField[];
+ };
+}
+
+export interface IVisualizationContainerPropsVis {
+ vis: IVisualizationTypeDefination;
+}
+
+export interface IConfigPanelTab {
+ id: string;
+ name: string;
+ mapTo: string;
+ editor: React.ReactNode;
+ sections: IConfigPanelOptions[];
+ props?: any;
+}
+
+export interface IConfigPanelOptions {
+ id: string;
+ name: string;
+ mapTo: string;
+ editor: React.ReactNode;
+ schemas: IConfigPanelOptionSection[];
+}
+
+export interface IConfigPanelOptionSection {
+ name: string;
+ component: null;
+ mapTo: 'mode';
+ props?: any;
+ isSingleSelection?: boolean;
+}
+
+export interface IVisualizationTypeDefination {
+ name: string;
+ type: string;
+ id: string;
+ label: string;
+ fullLabel: string;
+ category: string;
+ icon: React.ReactNode;
+ editorConfig: {
+ panelTabs: IConfigPanelTab;
+ };
+ visConfig: {
+ layout: Partial;
+ config: Partial;
+ };
+ component: React.ReactNode;
+}
+
+export interface IVisualizationContainerProps {
+ data: IVisualizationContainerPropsData;
+ vis: IVisualizationContainerPropsVis;
+}
+
+export interface IDefaultTimestampState {
+ hasSchemaConflict: boolean;
+ default_timestamp: string;
+ message: string;
+}
+
+export interface LiveTailProps {
+ isLiveTailOn: boolean;
+ setIsLiveTailPopoverOpen: React.Dispatch>;
+ liveTailName: string;
+ isLiveTailPopoverOpen: boolean;
+ dataTestSubj: string;
+}
diff --git a/dashboards-observability/common/types/notebooks.ts b/dashboards-observability/common/types/notebooks.ts
new file mode 100644
index 000000000..5c193ab5d
--- /dev/null
+++ b/dashboards-observability/common/types/notebooks.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { RefObject } from 'react';
+import { DashboardStart } from "../../../../src/plugins/dashboard/public";
+import { NavigationPublicPluginStart } from "../../../../src/plugins/navigation/public";
+
+export interface NotebooksPluginSetup {
+ getGreeting: () => string;
+}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface NotebooksPluginStart {}
+
+export interface optionsType {
+ baseUrl: string;
+ payload?: any;
+ headers?: any;
+ redirects?: number;
+ beforeRedirect?: any;
+ redirected?: any;
+ timeout?: number; // default: unlimited
+ maxBytes?: number; // default: unlimited
+ rejectUnauthorized?: boolean;
+ secureProtocol?: string; // The SSL method to use
+ ciphers?: string; // The TLS ciphers to support
+}
+
+export type ParaType = {
+ uniqueId: string;
+ isRunning: boolean;
+ inQueue: boolean;
+ isSelected: boolean;
+ isInputHidden: boolean;
+ isOutputHidden: boolean;
+ showAddPara: boolean;
+ isVizualisation: boolean;
+ vizObjectInput: string;
+ id: number;
+ inp: string;
+ lang: string;
+ editorLanguage: string;
+ typeOut: Array;
+ out: any[];
+ isInputExpanded: boolean;
+ isOutputStale: boolean;
+ paraRef: RefObject;
+ paraDivRef: RefObject;
+ visStartTime?: string;
+ visEndTime?: string;
+ visSavedObjId?: string;
+};
diff --git a/dashboards-observability/common/utils/index.ts b/dashboards-observability/common/utils/index.ts
new file mode 100644
index 000000000..e5f765ccd
--- /dev/null
+++ b/dashboards-observability/common/utils/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { getIndexPatternFromRawQuery, preprocessQuery, buildQuery } from './query_utils';
+export { uiSettingsService } from './settings_service';
diff --git a/dashboards-observability/common/utils/query_utils.ts b/dashboards-observability/common/utils/query_utils.ts
new file mode 100644
index 000000000..985964d7b
--- /dev/null
+++ b/dashboards-observability/common/utils/query_utils.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import datemath from '@elastic/datemath';
+import { isEmpty } from 'lodash';
+import { DATE_PICKER_FORMAT } from '../../common/constants/explorer';
+import {
+ PPL_INDEX_INSERT_POINT_REGEX,
+ PPL_INDEX_REGEX,
+ PPL_NEWLINE_REGEX,
+} from '../../common/constants/shared';
+
+export const getIndexPatternFromRawQuery = (query: string): string => {
+ const matches = query.match(PPL_INDEX_REGEX);
+ if (matches) {
+ return matches[2];
+ }
+ return '';
+};
+
+// insert time filter command and additional commands based on raw query
+export const preprocessQuery = ({
+ rawQuery,
+ startTime,
+ endTime,
+ timeField,
+ isLiveQuery,
+}: {
+ rawQuery: string;
+ startTime: string;
+ endTime: string;
+ timeField?: string;
+ isLiveQuery: boolean;
+}) => {
+ let finalQuery = '';
+
+ if (isEmpty(rawQuery)) return finalQuery;
+
+ // convert to moment
+ const start = datemath.parse(startTime)?.utc().format(DATE_PICKER_FORMAT);
+ const end = datemath.parse(endTime, { roundUp: true })?.utc().format(DATE_PICKER_FORMAT);
+ const tokens = rawQuery.replaceAll(PPL_NEWLINE_REGEX, '').match(PPL_INDEX_INSERT_POINT_REGEX);
+
+ if (isEmpty(tokens)) return finalQuery;
+
+ finalQuery = `${tokens![1]}=${
+ tokens![2]
+ } | where ${timeField} >= '${start}' and ${timeField} <= '${end}'${tokens![3]}`;
+ if (isLiveQuery) {
+ finalQuery = finalQuery + ` | sort - ${timeField}`;
+ }
+ return finalQuery;
+};
+
+export const buildQuery = (baseQuery: string, currQuery: string) => {
+ let fullQuery: string;
+ if (baseQuery) {
+ fullQuery = baseQuery;
+ if (currQuery) {
+ fullQuery += '| ' + currQuery;
+ }
+ } else {
+ fullQuery = currQuery;
+ }
+ return fullQuery;
+};
diff --git a/dashboards-observability/common/utils/settings_service.ts b/dashboards-observability/common/utils/settings_service.ts
new file mode 100644
index 000000000..f22912127
--- /dev/null
+++ b/dashboards-observability/common/utils/settings_service.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { IUiSettingsClient, NotificationsStart, ToastInput } from '../../../../src/core/public';
+
+let uiSettings: IUiSettingsClient;
+let notifications: NotificationsStart;
+
+export const uiSettingsService = {
+ init: (client: IUiSettingsClient, notificationsStart: NotificationsStart) => {
+ uiSettings = client;
+ notifications = notificationsStart;
+ },
+ get: (key: string, defaultOverride?: any) => {
+ return uiSettings?.get(key, defaultOverride) || '';
+ },
+ set: (key: string, value: any) => {
+ return uiSettings?.set(key, value) || Promise.reject("uiSettings client not initialized.");
+ },
+ addToast: (toast: ToastInput) => {
+ return notifications.toasts.add(toast);
+ }
+};
\ No newline at end of file
diff --git a/cypress.json b/dashboards-observability/cypress.json
similarity index 61%
rename from cypress.json
rename to dashboards-observability/cypress.json
index a9031a58f..5de5badf6 100644
--- a/cypress.json
+++ b/dashboards-observability/cypress.json
@@ -1,15 +1,21 @@
{
"baseUrl": "http://localhost:5601",
"video": true,
+ "chromeWebSecurity": false,
"fixturesFolder": ".cypress/fixtures",
"integrationFolder": ".cypress/integration",
"pluginsFile": ".cypress/plugins/index.js",
"screenshotsFolder": ".cypress/screenshots",
"supportFile": ".cypress/support/index.js",
"videosFolder": ".cypress/videos",
- "viewportWidth": 1600,
- "viewportHeight": 1600,
+ "viewportWidth": 2000,
+ "viewportHeight": 1320,
"requestTimeout": 60000,
"responseTimeout": 60000,
- "defaultCommandTimeout": 60000
+ "defaultCommandTimeout": 60000,
+ "env": {
+ "opensearch": "localhost:9200",
+ "opensearchDashboards": "localhost:5601",
+ "security_enabled": true
+ }
}
diff --git a/opensearch-dashboards-plugin-helpers.dev.json b/dashboards-observability/opensearch-dashboards-plugin-helpers.dev.json
similarity index 100%
rename from opensearch-dashboards-plugin-helpers.dev.json
rename to dashboards-observability/opensearch-dashboards-plugin-helpers.dev.json
diff --git a/dashboards-observability/opensearch_dashboards.json b/dashboards-observability/opensearch_dashboards.json
new file mode 100644
index 000000000..93a15121e
--- /dev/null
+++ b/dashboards-observability/opensearch_dashboards.json
@@ -0,0 +1,19 @@
+{
+ "id": "observabilityDashboards",
+ "version": "1.3.4.0",
+ "opensearchDashboardsVersion": "1.3.4",
+ "server": true,
+ "ui": true,
+ "requiredPlugins": [
+ "charts",
+ "data",
+ "embeddable",
+ "inspector",
+ "urlForwarding",
+ "navigation",
+ "uiActions",
+ "dashboard",
+ "visualizations",
+ "opensearchDashboardsReact"
+ ]
+}
diff --git a/dashboards-observability/package.json b/dashboards-observability/package.json
new file mode 100644
index 000000000..d88a5ae5b
--- /dev/null
+++ b/dashboards-observability/package.json
@@ -0,0 +1,44 @@
+{
+ "name": "observability-dashboards",
+ "version": "1.3.4.0",
+ "main": "index.ts",
+ "license": "Apache-2.0",
+ "scripts": {
+ "osd": "node ../../scripts/osd",
+ "build": "yarn plugin_helpers build",
+ "test": "../../node_modules/.bin/jest --config ./test/jest.config.js",
+ "cypress:run": "TZ=America/Los_Angeles cypress run",
+ "cypress:open": "TZ=America/Los_Angeles cypress open",
+ "plugin_helpers": "node ../../scripts/plugin_helpers"
+ },
+ "dependencies": {
+ "@algolia/autocomplete-core": "^1.4.1",
+ "@algolia/autocomplete-theme-classic": "^1.2.1",
+ "@nteract/outputs": "^3.0.11",
+ "@nteract/presentational-components": "^3.4.3",
+ "@reduxjs/toolkit": "^1.6.1",
+ "plotly.js-dist": "^2.2.0",
+ "react-graph-vis": "^1.0.5",
+ "react-plotly.js": "^2.5.1"
+ },
+ "devDependencies": {
+ "@types/enzyme-adapter-react-16": "^1.0.6",
+ "@types/react-plotly.js": "^2.5.0",
+ "@types/react-test-renderer": "^16.9.1",
+ "@cypress/skip-test": "^2.6.1",
+ "cypress": "^5.0.0",
+ "enzyme-adapter-react-16": "^1.15.2",
+ "eslint": "^6.8.0",
+ "jest-dom": "^4.0.0",
+ "performance-now": "^2.1.0"
+ },
+ "resolutions": {
+ "react-syntax-highlighter": "^15.4.3",
+ "prismjs": "^1.22.0",
+ "trim": "^1.0.0",
+ "lodash": "^4.17.21",
+ "glob-parent": "^6.0.1",
+ "ansi-regex": "^5.0.1",
+ "json-schema": "^0.4.0"
+ }
+}
diff --git a/dashboards-observability/public/components/app.tsx b/dashboards-observability/public/components/app.tsx
new file mode 100644
index 000000000..36594b890
--- /dev/null
+++ b/dashboards-observability/public/components/app.tsx
@@ -0,0 +1,139 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { I18nProvider } from '@osd/i18n/react';
+import React from 'react';
+import { Provider } from 'react-redux';
+import { HashRouter, Route, Switch } from 'react-router-dom';
+import { CoreStart } from '../../../../src/core/public';
+import { observabilityID, observabilityTitle } from '../../common/constants/shared';
+import store from '../framework/redux/store';
+import { AppPluginStartDependencies } from '../types';
+import { Home as ApplicationAnalyticsHome } from './application_analytics/home';
+import { Home as CustomPanelsHome } from './custom_panels/home';
+import { EventAnalytics } from './explorer/event_analytics';
+import { Main as NotebooksHome } from './notebooks/components/main';
+import { Home as TraceAnalyticsHome } from './trace_analytics/home';
+
+interface ObservabilityAppDeps {
+ CoreStartProp: CoreStart;
+ DepsStart: AppPluginStartDependencies;
+ pplService: any;
+ dslService: any;
+ savedObjects: any;
+ timestampUtils: any;
+}
+
+export const App = ({
+ CoreStartProp,
+ DepsStart,
+ pplService,
+ dslService,
+ savedObjects,
+ timestampUtils,
+}: ObservabilityAppDeps) => {
+ const { chrome, http, notifications } = CoreStartProp;
+ const parentBreadcrumb = {
+ text: observabilityTitle,
+ href: `${observabilityID}#/`,
+ };
+
+ const customPanelBreadcrumb = {
+ text: 'Operational panels',
+ href: '#/operational_panels/',
+ };
+
+ return (
+
+
+
+ <>
+
+ {
+ return (
+
+ );
+ }}
+ />
+ (
+
+ )}
+ />
+ {
+ chrome.setBreadcrumbs([parentBreadcrumb, customPanelBreadcrumb]);
+ return (
+
+ );
+ }}
+ />
+ (
+
+ )}
+ />
+ {
+ return (
+
+ );
+ }}
+ />
+
+ >
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap
new file mode 100644
index 000000000..079cdc1b1
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/create.test.tsx.snap
@@ -0,0 +1,18907 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Create Page can clear query 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page clears one trace selected 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page clears service selected 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page renders empty 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page renders with name and description 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page renders with one service selected 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page renders with one trace selected 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
+
+exports[`Create Page renders with query 1`] = `
+Object {
+ "asFragment": [Function],
+ "baseElement":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
+
+ ,
+ "container":
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+ 0
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+ 0
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No matches
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+
+
+
+ Create and Set Availability
+
+
+
+
+
+
+
+
+
+
,
+ "debug": [Function],
+ "findAllByAltText": [Function],
+ "findAllByDisplayValue": [Function],
+ "findAllByLabelText": [Function],
+ "findAllByPlaceholderText": [Function],
+ "findAllByRole": [Function],
+ "findAllByTestId": [Function],
+ "findAllByText": [Function],
+ "findAllByTitle": [Function],
+ "findByAltText": [Function],
+ "findByDisplayValue": [Function],
+ "findByLabelText": [Function],
+ "findByPlaceholderText": [Function],
+ "findByRole": [Function],
+ "findByTestId": [Function],
+ "findByText": [Function],
+ "findByTitle": [Function],
+ "getAllByAltText": [Function],
+ "getAllByDisplayValue": [Function],
+ "getAllByLabelText": [Function],
+ "getAllByPlaceholderText": [Function],
+ "getAllByRole": [Function],
+ "getAllByTestId": [Function],
+ "getAllByText": [Function],
+ "getAllByTitle": [Function],
+ "getByAltText": [Function],
+ "getByDisplayValue": [Function],
+ "getByLabelText": [Function],
+ "getByPlaceholderText": [Function],
+ "getByRole": [Function],
+ "getByTestId": [Function],
+ "getByText": [Function],
+ "getByTitle": [Function],
+ "queryAllByAltText": [Function],
+ "queryAllByDisplayValue": [Function],
+ "queryAllByLabelText": [Function],
+ "queryAllByPlaceholderText": [Function],
+ "queryAllByRole": [Function],
+ "queryAllByTestId": [Function],
+ "queryAllByText": [Function],
+ "queryAllByTitle": [Function],
+ "queryByAltText": [Function],
+ "queryByDisplayValue": [Function],
+ "queryByLabelText": [Function],
+ "queryByPlaceholderText": [Function],
+ "queryByRole": [Function],
+ "queryByTestId": [Function],
+ "queryByText": [Function],
+ "queryByTitle": [Function],
+ "rerender": [Function],
+ "unmount": [Function],
+}
+`;
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/log_config.test.tsx.snap b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/log_config.test.tsx.snap
new file mode 100644
index 000000000..f5bdb4cac
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/log_config.test.tsx.snap
@@ -0,0 +1,966 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Log Config component renders empty log config 1`] = `
+
+
+
+
+
+ Log source
+
+
+
+
+ Configure your application base query
+
+
+ }
+ data-test-subj="logSourceAccordion"
+ extraAction={
+
+ Clear
+
+ }
+ id="logSource"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You can't change the base query after the application is created.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base Query
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PPL
+
+
+
+
+
+
+
+
+
+ The default logs view in the application will be filtered by this query.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Log Config component renders with query 1`] = `
+
+
+
+
+
+ Log source
+
+
+
+
+ Configure your application base query
+
+
+ }
+ data-test-subj="logSourceAccordion"
+ extraAction={
+
+ Clear
+
+ }
+ id="logSource"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+
+
+
+
+
+
+
+ Configure your application base query
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You can't change the base query after the application is created.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base Query
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PPL
+
+
+
+
+
+
+
+
+
+ The default logs view in the application will be filtered by this query.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap
new file mode 100644
index 000000000..8ffca27ab
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/service_config.test.tsx.snap
@@ -0,0 +1,2157 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Service Config component renders empty service config 1`] = `
+
+
+
+
+
+ Services & entities
+
+
+ 0
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+ }
+ data-test-subj="servicesEntitiesAccordion"
+ extraAction={
+
+ Clear all
+
+ }
+ id="servicesEntities"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+
+
+
+
+
+
+
+
+ Select services and entities
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Service Config component renders with one service selected 1`] = `
+
+
+
+
+
+ Services & entities
+
+
+ 0
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+ }
+ data-test-subj="servicesEntitiesAccordion"
+ extraAction={
+
+ Clear all
+
+ }
+ id="servicesEntities"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select services & entities to include in this application
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services & entities
+
+
+
+
+
+
+
+
+
+
+
+
+ Select services and entities
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/trace_config.test.tsx.snap b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/trace_config.test.tsx.snap
new file mode 100644
index 000000000..395900132
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/__snapshots__/trace_config.test.tsx.snap
@@ -0,0 +1,1587 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Trace Config component renders empty trace config 1`] = `
+
+
+
+
+
+ Trace groups
+
+
+ 0
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+ }
+ data-test-subj="traceGroupsAccordion"
+ extraAction={
+
+ Clear all
+
+ }
+ id="traceGroups"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace Groups
+
+
+
+
+
+
+
+
+
+
+
+
+ Select or add trace groups
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select one or multiple trace groups, or type a custom one
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ □
+
+ < 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ■
+
+ >= 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Trace Config component renders with one trace selected 1`] = `
+
+
+
+
+
+ Trace groups
+
+
+ 0
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+ }
+ data-test-subj="traceGroupsAccordion"
+ extraAction={
+
+ Clear all
+
+ }
+ id="traceGroups"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ onToggle={[Function]}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace groups
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Constrain your application to specific trace groups
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Clear all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace Groups
+
+
+
+
+
+
+
+
+
+
+
+
+ Select or add trace groups
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select one or multiple trace groups, or type a custom one
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ □
+
+ < 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ■
+
+ >= 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/create.test.tsx b/dashboards-observability/public/components/application_analytics/__tests__/create.test.tsx
new file mode 100644
index 000000000..5fda0c03a
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/create.test.tsx
@@ -0,0 +1,583 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { CreateApp } from '../components/create';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+import DSLService from 'public/services/requests/dsl';
+import PPLService from 'public/services/requests/ppl';
+import { render } from '@testing-library/react';
+
+describe('Create Page', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const utils = render(
+
+ );
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('renders with name and description', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const utils = render(
+
+ );
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('renders with query', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const utils = render(
+
+ );
+ utils.getByText('Log source').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Cancel').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('can clear query', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const utils = render(
+
+ );
+ utils.getByText('Log source').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Clear').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('renders with one service selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const serviceFilters = [
+ {
+ field: 'serviceName',
+ operator: 'is',
+ value: 'User',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const utils = render(
+
+ );
+ utils.getByText('Select services & entities to include in this application').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Cancel').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('clears service selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const serviceFilters = [
+ {
+ field: 'serviceName',
+ operator: 'is',
+ value: 'User',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const utils = render(
+
+ );
+ utils.getByText('Select services & entities to include in this application').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Clear').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('renders with one trace selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const traceFilters = [
+ {
+ field: 'traceGroup',
+ operator: 'is',
+ value: 'test.auto',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const utils = render(
+
+ );
+ utils.getByText('Constrain your application to specific trace groups').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Cancel').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+
+ it('clears one trace selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const createApp = jest.fn();
+ const setToasts = jest.fn();
+ const updateApp = jest.fn();
+ const clearStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const pplService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ } as unknown) as PPLService;
+ const traceFilters = [
+ {
+ field: 'traceGroup',
+ operator: 'is',
+ value: 'test.auto',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const utils = render(
+
+ );
+ utils.getByText('Constrain your application to specific trace groups').click();
+ utils.getByText('Clear').click();
+ utils.getByText('Clear').click();
+
+ expect(utils).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/log_config.test.tsx b/dashboards-observability/public/components/application_analytics/__tests__/log_config.test.tsx
new file mode 100644
index 000000000..f1d0781d8
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/log_config.test.tsx
@@ -0,0 +1,121 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { LogConfig } from '../components/config_components/log_config';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+import DSLService from 'public/services/requests/dsl';
+
+describe('Log Config component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty log config', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsFlyoutVisible = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders with query', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsFlyoutVisible = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/service_config.test.tsx b/dashboards-observability/public/components/application_analytics/__tests__/service_config.test.tsx
new file mode 100644
index 000000000..d574ba942
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/service_config.test.tsx
@@ -0,0 +1,130 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { ServiceConfig } from '../components/config_components/service_config';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+import DSLService from 'public/services/requests/dsl';
+
+describe('Service Config component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty service config', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setSelectedServices = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders with one service selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setSelectedServices = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const setAppConfigs = jest.fn();
+ const setStartTimeWithStorage = jest.fn();
+ const setEndTimeWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const serviceFilter = [
+ {
+ field: 'serviceName',
+ operator: 'is',
+ value: 'User',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/application_analytics/__tests__/trace_config.test.tsx b/dashboards-observability/public/components/application_analytics/__tests__/trace_config.test.tsx
new file mode 100644
index 000000000..10a524fe2
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/__tests__/trace_config.test.tsx
@@ -0,0 +1,116 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { TraceConfig } from '../components/config_components/trace_config';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+import DSLService from 'public/services/requests/dsl';
+
+describe('Trace Config component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty trace config', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setSelectedTraces = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders with one trace selected', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setSelectedTraces = jest.fn();
+ const setNameWithStorage = jest.fn();
+ const setDescriptionWithStorage = jest.fn();
+ const setQueryWithStorage = jest.fn();
+ const setFiltersWithStorage = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const traceFilter = [
+ {
+ field: 'traceGroup',
+ operator: 'is',
+ value: 'test.auto',
+ inverted: false,
+ disabled: false,
+ },
+ ];
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/application_analytics/app_analytics.scss b/dashboards-observability/public/components/application_analytics/app_analytics.scss
new file mode 100644
index 000000000..ad05f6544
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/app_analytics.scss
@@ -0,0 +1,29 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.query-area {
+ width: 900px;
+}
+
+#logSource {
+ overflow: visible;
+ position: relative;
+ z-index: 10;
+ .ppl-link {
+ top: 103px;
+ right: 140px;
+ }
+}
+
+#baseQueryCallout {
+ max-width: 900px;
+}
+
+#compositionColumn {
+ width: 300px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/app_table.tsx b/dashboards-observability/public/components/application_analytics/components/app_table.tsx
new file mode 100644
index 000000000..75fe228af
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/app_table.tsx
@@ -0,0 +1,344 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import '../app_analytics.scss';
+import {
+ EuiBadge,
+ EuiButton,
+ EuiContextMenuItem,
+ EuiContextMenuPanel,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHorizontalRule,
+ EuiInMemoryTable,
+ EuiLink,
+ EuiLoadingSpinner,
+ EuiOverlayMask,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiPopover,
+ EuiSpacer,
+ EuiTableFieldDataColumnType,
+ EuiText,
+ EuiTitle,
+ EuiToolTip,
+} from '@elastic/eui';
+import _ from 'lodash';
+import React, { ReactElement, useEffect, useState } from 'react';
+import moment from 'moment';
+import { DeleteModal } from '../../common/helpers/delete_modal';
+import { AppAnalyticsComponentDeps } from '../home';
+import { getCustomModal } from '../../custom_panels/helpers/modal_containers';
+import { pageStyles, UI_DATE_FORMAT } from '../../../../common/constants/shared';
+import { ApplicationType, AvailabilityType } from '../../../../common/types/application_analytics';
+
+interface AppTableProps extends AppAnalyticsComponentDeps {
+ loading: boolean;
+ applications: ApplicationType[];
+ fetchApplications: () => void;
+ renameApplication: (newAppName: string, appId: string) => void;
+ deleteApplication: (appList: string[], panelIdList: string[], toastMessage?: string) => void;
+ clearStorage: () => void;
+ moveToApp: (id: string, type: string) => void;
+}
+
+export function AppTable(props: AppTableProps) {
+ const {
+ chrome,
+ applications,
+ parentBreadcrumbs,
+ fetchApplications,
+ renameApplication,
+ deleteApplication,
+ setFilters,
+ clearStorage,
+ moveToApp,
+ } = props;
+ const [isModalVisible, setIsModalVisible] = useState(false);
+ const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false);
+ const [modalLayout, setModalLayout] = useState( );
+ const [selectedApplications, setSelectedApplications] = useState([]);
+ const createButtonText = 'Create application';
+
+ useEffect(() => {
+ chrome.setBreadcrumbs([
+ ...parentBreadcrumbs,
+ {
+ text: 'Application analytics',
+ href: '#/application_analytics',
+ },
+ ]);
+ clear();
+ fetchApplications();
+ }, []);
+
+ const clear = () => {
+ setFilters([]);
+ clearStorage();
+ };
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onRename = async (newApplicationName: string) => {
+ renameApplication(newApplicationName, selectedApplications[0].id);
+ closeModal();
+ };
+
+ const onDelete = async () => {
+ closeModal();
+ const toastMessage = `Application${
+ selectedApplications.length > 1 ? 's' : ' "' + selectedApplications[0].name + '"'
+ } successfully deleted!`;
+ await deleteApplication(
+ selectedApplications.map((app) => app.id),
+ selectedApplications.map((app) => app.panelId),
+ toastMessage
+ );
+ };
+
+ const renameApp = () => {
+ setModalLayout(
+ getCustomModal(
+ onRename,
+ closeModal,
+ 'Name',
+ 'Rename application',
+ 'Cancel',
+ 'Rename',
+ selectedApplications[0].name
+ )
+ );
+ showModal();
+ };
+
+ const deleteApp = () => {
+ const applicationString = `application${selectedApplications.length > 1 ? 's' : ''}`;
+ setModalLayout(
+
+ );
+ showModal();
+ };
+
+ const popoverButton = (
+ setIsActionsPopoverOpen(!isActionsPopoverOpen)}
+ >
+ Actions
+
+ );
+
+ const popoverItems: ReactElement[] = [
+ {
+ setIsActionsPopoverOpen(false);
+ renameApp();
+ }}
+ >
+ Rename
+ ,
+ //
+ // Duplicate
+ // ,
+ {
+ setIsActionsPopoverOpen(false);
+ deleteApp();
+ }}
+ >
+ Delete
+ ,
+ // Add sample application ,
+ ];
+
+ const renderAvailability = (value: AvailabilityType, record: ApplicationType) => {
+ if (value.color === 'loading') {
+ return ;
+ } else if (value.name) {
+ return (
+
+ {value.name}
+
+ );
+ } else if (value.color === 'undefined') {
+ return No match ;
+ } else if (value.color === 'null') {
+ return - ;
+ } else {
+ return (
+ moveToApp(record.id, 'createSetAvailability')}
+ >
+ Set Availability
+
+ );
+ }
+ };
+
+ const tableColumns = [
+ {
+ field: 'name',
+ name: 'Name',
+ sortable: true,
+ truncateText: true,
+ render: (value, record) => (
+
+ {_.truncate(record.name, { length: 100 })}
+
+ ),
+ },
+ {
+ field: 'composition',
+ name: 'Composition',
+ sortable: false,
+ truncateText: true,
+ render: (value, record) => (
+
+
+ {record.servicesEntities.concat(record.traceGroups).join(', ')}
+
+
+ ),
+ },
+ {
+ field: 'availability',
+ name: 'Current Availability',
+ sortable: true,
+ render: renderAvailability,
+ },
+ {
+ field: 'dateModified',
+ name: 'Date Modified',
+ sortable: true,
+ render: (value) => {moment(value).format(UI_DATE_FORMAT)} ,
+ },
+ ] as Array>;
+
+ return (
+
+
+
+
+
+
+ Overview
+
+
+
+
+
+
+
+
+ Applications ({applications.length})
+
+
+
+
+
+
+ setIsActionsPopoverOpen(false)}
+ >
+
+
+
+
+
+ {createButtonText}
+
+
+
+
+
+
+ {applications.length > 0 ? (
+ setSelectedApplications(items),
+ }}
+ />
+ ) : (
+ <>
+
+
+ No applications
+
+
+
+
+
+ {createButtonText}
+
+
+ {/*
+ Add sample applications
+ */}
+
+
+ >
+ )}
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/application.tsx b/dashboards-observability/public/components/application_analytics/components/application.tsx
new file mode 100644
index 000000000..97816ea88
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/application.tsx
@@ -0,0 +1,576 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable no-console */
+
+import {
+ EuiHorizontalRule,
+ EuiPage,
+ EuiPageBody,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiPanel,
+ EuiSelectOption,
+ EuiSpacer,
+ EuiTabbedContent,
+ EuiTabbedContentTab,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import PPLService from 'public/services/requests/ppl';
+import SavedObjects from 'public/services/saved_objects/event_analytics/saved_objects';
+import TimestampUtils from 'public/services/timestamp/timestamp';
+import React, { ReactChild, useEffect, useState } from 'react';
+import { useHistory } from 'react-router-dom';
+import { useDispatch } from 'react-redux';
+import { last } from 'lodash';
+import { VisualizationType } from 'common/types/custom_panels';
+import { TracesContent } from '../../../components/trace_analytics/components/traces/traces_content';
+import { DashboardContent } from '../../../components/trace_analytics/components/dashboard/dashboard_content';
+import { ServicesContent } from '../../trace_analytics/components/services/services_content';
+import {
+ filtersToDsl,
+ PanelTitle,
+} from '../../../../public/components/trace_analytics/components/common/helper_functions';
+import { SpanDetailTable } from '../../../../public/components/trace_analytics/components/traces/span_detail_table';
+import { Explorer } from '../../explorer/explorer';
+import { Configuration } from './configuration';
+import {
+ TAB_CONFIG_ID,
+ TAB_CONFIG_TITLE,
+ TAB_LOG_ID,
+ TAB_LOG_TITLE,
+ TAB_OVERVIEW_ID,
+ TAB_OVERVIEW_TITLE,
+ TAB_PANEL_ID,
+ TAB_PANEL_TITLE,
+ TAB_SERVICE_ID,
+ TAB_SERVICE_TITLE,
+ TAB_TRACE_ID,
+ TAB_TRACE_TITLE,
+} from '../../../../common/constants/application_analytics';
+import { TAB_EVENT_ID, TAB_CHART_ID, NEW_TAB } from '../../../../common/constants/explorer';
+import { IQueryTab } from '../../../../common/types/explorer';
+import { NotificationsStart } from '../../../../../../src/core/public';
+import { AppAnalyticsComponentDeps } from '../home';
+import { CustomPanelView } from '../../../../public/components/custom_panels/custom_panel_view';
+import {
+ ApplicationRequestType,
+ ApplicationType,
+} from '../../../../common/types/application_analytics';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../common/constants/custom_panels';
+import { ServiceDetailFlyout } from './flyout_components/service_detail_flyout';
+import { SpanDetailFlyout } from '../../../../public/components/trace_analytics/components/traces/span_detail_flyout';
+import { TraceDetailFlyout } from './flyout_components/trace_detail_flyout';
+import { fetchAppById, initializeTabData } from '../helpers/utils';
+
+const searchBarConfigs = {
+ [TAB_EVENT_ID]: {
+ showSaveButton: false,
+ showSavePanelOptionsList: false,
+ },
+ [TAB_CHART_ID]: {
+ showSaveButton: true,
+ showSavePanelOptionsList: false,
+ },
+};
+
+interface AppDetailProps extends AppAnalyticsComponentDeps {
+ disabled?: boolean;
+ appId: string;
+ pplService: PPLService;
+ dslService: DSLService;
+ savedObjects: SavedObjects;
+ timestampUtils: TimestampUtils;
+ notifications: NotificationsStart;
+ updateApp: (appId: string, updateAppData: Partial, type: string) => void;
+ setToasts: (title: string, color?: string, text?: ReactChild) => void;
+ callback: (childfunction: () => void) => void;
+}
+
+export function Application(props: AppDetailProps) {
+ const {
+ pplService,
+ dslService,
+ timestampUtils,
+ savedObjects,
+ http,
+ notifications,
+ appId,
+ chrome,
+ parentBreadcrumbs,
+ query,
+ filters,
+ appConfigs,
+ updateApp,
+ setAppConfigs,
+ setToasts,
+ setFilters,
+ callback,
+ } = props;
+ const [application, setApplication] = useState({
+ id: '',
+ dateCreated: '',
+ dateModified: '',
+ name: '',
+ description: '',
+ baseQuery: '',
+ servicesEntities: [],
+ traceGroups: [],
+ panelId: '',
+ availability: { name: '', color: '', availabilityVisId: '' },
+ });
+ const dispatch = useDispatch();
+ const [triggerAvailability, setTriggerAvailability] = useState(false);
+ const [selectedTabId, setSelectedTab] = useState(TAB_OVERVIEW_ID);
+ const [serviceFlyoutName, setServiceFlyoutName] = useState('');
+ const [traceFlyoutId, setTraceFlyoutId] = useState('');
+ const [spanFlyoutId, setSpanFlyoutId] = useState('');
+ const [spanDSL, setSpanDSL] = useState({});
+ const [totalSpans, setTotalSpans] = useState(0);
+ const [editVizId, setEditVizId] = useState('');
+ const [visWithAvailability, setVisWithAvailability] = useState([]);
+ const handleContentTabClick = (selectedTab: IQueryTab) => setSelectedTab(selectedTab.id);
+ const [appStartTime, setAppStartTime] = useState(
+ sessionStorage.getItem(`${application.name}StartTime`) || 'now-24h'
+ );
+ const [appEndTime, setAppEndTime] = useState(
+ sessionStorage.getItem(`${application.name}EndTime`) || 'now'
+ );
+
+ const history = useHistory();
+
+ const setStartTimeForApp = (newStartTime: string) => {
+ setAppStartTime(newStartTime);
+ sessionStorage.setItem(`${application.name}StartTime`, newStartTime);
+ };
+ const setEndTimeForApp = (newEndTime: string) => {
+ setAppEndTime(newEndTime);
+ sessionStorage.setItem(`${application.name}EndTime`, newEndTime);
+ };
+
+ const addSpanFilter = (field: string, value: any) => {
+ const newFilters = [...filters];
+ const index = newFilters.findIndex(({ field: filterField }) => field === filterField);
+ if (index === -1) {
+ newFilters.push({ field, operator: 'is', value, inverted: false, disabled: false });
+ } else {
+ newFilters.splice(index, 1, {
+ field,
+ operator: 'is',
+ value,
+ inverted: false,
+ disabled: false,
+ });
+ }
+ setFilters(newFilters);
+ };
+
+ // Add visualization to application's panel
+ const addVisualizationToPanel = async (visualizationId: string, visualizationName: string) => {
+ return http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/visualizations`, {
+ body: JSON.stringify({
+ panelId: application.panelId,
+ savedVisualizationId: visualizationId,
+ }),
+ })
+ .then(() => {
+ fetchAppById(
+ http,
+ pplService,
+ appId,
+ setApplication,
+ setAppConfigs,
+ setVisWithAvailability,
+ setToasts
+ );
+ })
+ .catch((err) => {
+ setToasts(`Error in adding ${visualizationName} visualization to the panel`, 'danger');
+ console.error(err);
+ });
+ };
+
+ useEffect(() => {
+ fetchAppById(
+ http,
+ pplService,
+ appId,
+ setApplication,
+ setAppConfigs,
+ setVisWithAvailability,
+ setToasts
+ );
+ const tabId = `application-analytics-tab-${appId}`;
+ initializeTabData(dispatch, tabId, NEW_TAB);
+ callback(switchToEvent);
+ }, [appId]);
+
+ useEffect(() => {
+ chrome.setBreadcrumbs([
+ ...parentBreadcrumbs,
+ {
+ text: 'Application analytics',
+ href: '#/application_analytics',
+ },
+ {
+ text: application.name,
+ href: `${last(parentBreadcrumbs)!.href}application_analytics/${appId}`,
+ },
+ ]);
+ setStartTimeForApp(sessionStorage.getItem(`${application.name}StartTime`) || 'now-24h');
+ setEndTimeForApp(sessionStorage.getItem(`${application.name}EndTime`) || 'now');
+ }, [appId, application.name]);
+
+ useEffect(() => {
+ const DSL = filtersToDsl(filters, query, appStartTime, appEndTime, 'app', appConfigs);
+ setSpanDSL(DSL);
+ }, [filters, appConfigs, query, appStartTime, appEndTime]);
+
+ useEffect(() => {
+ if (selectedTabId !== TAB_LOG_ID) {
+ switchToEditViz('');
+ }
+ }, [selectedTabId]);
+
+ const openServiceFlyout = (serviceName: string) => {
+ setSpanFlyoutId('');
+ setTraceFlyoutId('');
+ setServiceFlyoutName(serviceName);
+ };
+
+ const closeServiceFlyout = () => {
+ setServiceFlyoutName('');
+ };
+
+ const openSpanFlyout = (spanId: string) => {
+ setServiceFlyoutName('');
+ setTraceFlyoutId('');
+ setSpanFlyoutId(spanId);
+ };
+
+ const closeSpanFlyout = () => {
+ setSpanFlyoutId('');
+ };
+
+ const openTraceFlyout = (traceId: string) => {
+ setServiceFlyoutName('');
+ setSpanFlyoutId('');
+ setTraceFlyoutId(traceId);
+ };
+
+ const closeTraceFlyout = () => {
+ setTraceFlyoutId('');
+ };
+
+ const childBreadcrumbs = [
+ {
+ text: 'Application analytics',
+ href: '#/application_analytics',
+ },
+ {
+ text: `${application.name}`,
+ href: `#/application_analytics/${appId}`,
+ },
+ ];
+
+ const getOverview = () => {
+ return (
+ <>
+
+
+ >
+ );
+ };
+
+ const nameColumnAction = (item: any) => openServiceFlyout(item);
+ const traceColumnAction = () => switchToTrace();
+
+ const getService = () => {
+ return (
+ <>
+
+
+ >
+ );
+ };
+
+ const switchToTrace = () => {
+ setSelectedTab(TAB_TRACE_ID);
+ };
+
+ const traceIdColumnAction = (item: any) => openTraceFlyout(item);
+
+ const getTrace = () => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+ };
+
+ const getLog = () => {
+ return (
+
+ );
+ };
+
+ const onEditClick = (savedVisualizationId: string) => {
+ switchToEditViz(savedVisualizationId);
+ };
+
+ const updateAvailabilityVizId = (vizs: VisualizationType[]) => {
+ if (
+ !vizs
+ .map((viz) => viz.savedVisualizationId)
+ .includes(application.availability.availabilityVisId)
+ ) {
+ updateApp(appId, { availabilityVisId: '' }, 'editAvailability');
+ }
+ };
+
+ const getPanel = () => {
+ return (
+ undefined}
+ cloneCustomPanel={async () => Promise.reject()}
+ deleteCustomPanel={async () => Promise.reject()}
+ setToast={setToasts}
+ page="app"
+ appId={appId}
+ updateAvailabilityVizId={updateAvailabilityVizId}
+ startTime={appStartTime}
+ endTime={appEndTime}
+ setStartTime={setStartTimeForApp}
+ setEndTime={setEndTimeForApp}
+ onAddClick={switchToEvent}
+ onEditClick={onEditClick}
+ />
+ );
+ };
+
+ const switchToEvent = () => {
+ setSelectedTab(TAB_LOG_ID);
+ };
+
+ const switchToEditViz = (savedVizId: string) => {
+ if (savedVizId) {
+ setEditVizId(savedVizId);
+ switchToEvent();
+ } else {
+ setEditVizId('');
+ }
+ };
+
+ const switchToAvailability = () => {
+ switchToEvent();
+ setTriggerAvailability(true);
+ };
+
+ const callbackInApp = (childFunc: () => void) => {
+ if (childFunc && triggerAvailability) {
+ childFunc();
+ setTriggerAvailability(false);
+ }
+ };
+
+ const getConfig = () => {
+ return (
+
+ );
+ };
+
+ function getAppAnalyticsTab({
+ tabId,
+ tabTitle,
+ getContent,
+ }: {
+ tabId: string;
+ tabTitle: string;
+ getContent: () => JSX.Element;
+ }) {
+ return {
+ id: tabId,
+ name: (
+ <>
+
+ {tabTitle}
+
+ >
+ ),
+ content: <>{getContent()}>,
+ };
+ }
+
+ const appAnalyticsTabs = [
+ getAppAnalyticsTab({
+ tabId: TAB_OVERVIEW_ID,
+ tabTitle: TAB_OVERVIEW_TITLE,
+ getContent: () => getOverview(),
+ }),
+ getAppAnalyticsTab({
+ tabId: TAB_SERVICE_ID,
+ tabTitle: TAB_SERVICE_TITLE,
+ getContent: () => getService(),
+ }),
+ getAppAnalyticsTab({
+ tabId: TAB_TRACE_ID,
+ tabTitle: TAB_TRACE_TITLE,
+ getContent: () => getTrace(),
+ }),
+ getAppAnalyticsTab({
+ tabId: TAB_LOG_ID,
+ tabTitle: TAB_LOG_TITLE,
+ getContent: () => getLog(),
+ }),
+ getAppAnalyticsTab({
+ tabId: TAB_PANEL_ID,
+ tabTitle: TAB_PANEL_TITLE,
+ getContent: () => getPanel(),
+ }),
+ getAppAnalyticsTab({
+ tabId: TAB_CONFIG_ID,
+ tabTitle: TAB_CONFIG_TITLE,
+ getContent: () => getConfig(),
+ }),
+ ];
+
+ return (
+
+
+
+
+
+
+ {application.name}
+
+
+ {application.description}
+
+
+
+ {
+ return tab.id === selectedTabId;
+ })}
+ onTabClick={(selectedTab: EuiTabbedContentTab) => handleContentTabClick(selectedTab)}
+ tabs={appAnalyticsTabs}
+ />
+
+ {serviceFlyoutName && (
+
+ )}
+ {spanFlyoutId && (
+
+ )}
+ {traceFlyoutId && (
+
+ )}
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/config_components/log_config.tsx b/dashboards-observability/public/components/application_analytics/components/config_components/log_config.tsx
new file mode 100644
index 000000000..fd0371bbd
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/config_components/log_config.tsx
@@ -0,0 +1,167 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiAccordion,
+ EuiText,
+ EuiSpacer,
+ EuiButton,
+ EuiFormRow,
+ EuiFlexItem,
+ EuiBadge,
+ EuiOverlayMask,
+ EuiCallOut,
+ EuiFlexGroup,
+} from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import React, { useState } from 'react';
+import {
+ parseGetSuggestions,
+ onItemSelect,
+} from '../../../../../public/components/common/search/autocomplete_logic';
+import { uiSettingsService } from '../../../../../common/utils';
+import { Autocomplete } from '../../../common/search/autocomplete';
+import { AppAnalyticsComponentDeps } from '../../home';
+import { getClearModal } from '../../helpers/modal_containers';
+import '../../app_analytics.scss';
+
+interface LogConfigProps extends AppAnalyticsComponentDeps {
+ dslService: DSLService;
+ setIsFlyoutVisible: any;
+ editMode: boolean;
+}
+
+export const LogConfig = (props: LogConfigProps) => {
+ const { dslService, query, setQueryWithStorage, setIsFlyoutVisible, editMode } = props;
+ const [logOpen, setLogOpen] = useState(false);
+ const [isModalVisible, setIsModalVisible] = useState(false);
+ const [modalLayout, setModalLayout] = useState( );
+ const [tempQuery, setTempQuery] = useState('');
+
+ const handleQueryChange = async (newQuery: string) => {
+ setTempQuery(newQuery);
+ setQueryWithStorage(newQuery);
+ };
+
+ const showFlyout = () => {
+ setIsFlyoutVisible(true);
+ };
+
+ const onCancel = () => {
+ setIsModalVisible(false);
+ };
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onConfirm = () => {
+ handleQueryChange('');
+ closeModal();
+ };
+
+ const clearAllModal = () => {
+ setModalLayout(
+ getClearModal(
+ onCancel,
+ onConfirm,
+ 'Clear log source?',
+ 'This will clear all information in log source configuration.',
+ 'Clear'
+ )
+ );
+ showModal();
+ };
+
+ const allowedCommands = [
+ { label: 'dedup' },
+ { label: 'eval' },
+ { label: 'fields' },
+ { label: 'parse' },
+ { label: 'rename' },
+ { label: 'sort' },
+ { label: 'where' },
+ ];
+
+ return (
+
+
+
+ Log source
+
+
+
+ Configure your application base query
+
+ >
+ }
+ extraAction={
+
+ Clear
+
+ }
+ onToggle={(isOpen) => {
+ setLogOpen(isOpen);
+ }}
+ paddingSize="l"
+ >
+
+
+
+ You can't change the base query after the application is created.
+
+
+
+
+
+ {}}
+ dslService={dslService}
+ getSuggestions={parseGetSuggestions}
+ onItemSelect={onItemSelect}
+ isDisabled={editMode}
+ tabId={'application-analytics-tab'}
+ possibleCommands={allowedCommands}
+ />
+
+ PPL
+
+
+
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/components/config_components/service_config.tsx b/dashboards-observability/public/components/application_analytics/components/config_components/service_config.tsx
new file mode 100644
index 000000000..30b78adcd
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/config_components/service_config.tsx
@@ -0,0 +1,193 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import {
+ EuiAccordion,
+ EuiBadge,
+ EuiButton,
+ EuiComboBox,
+ EuiFormRow,
+ EuiOverlayMask,
+ EuiSpacer,
+ EuiText,
+} from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import React, { useState } from 'react';
+import { useEffect } from 'react';
+import { FilterType } from '../../../trace_analytics/components/common/filters/filters';
+import { ServiceObject } from '../../../trace_analytics/components/common/plots/service_map';
+import { ServiceMap } from '../../../trace_analytics/components/services';
+import { handleServiceMapRequest } from '../../../trace_analytics/requests/services_request_handler';
+import { AppAnalyticsComponentDeps } from '../../home';
+import { OptionType } from '../../../../../common/types/application_analytics';
+import { getClearModal } from '../../helpers/modal_containers';
+
+interface ServiceConfigProps extends AppAnalyticsComponentDeps {
+ dslService: DSLService;
+ selectedServices: OptionType[];
+ setSelectedServices: (services: OptionType[]) => void;
+}
+
+export const ServiceConfig = (props: ServiceConfigProps) => {
+ const {
+ dslService,
+ filters,
+ setFiltersWithStorage,
+ http,
+ selectedServices,
+ setSelectedServices,
+ } = props;
+ const [servicesOpen, setServicesOpen] = useState(false);
+ const [serviceMap, setServiceMap] = useState({});
+ const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
+ 'latency' | 'error_rate' | 'throughput'
+ >('latency');
+ const [isModalVisible, setIsModalVisible] = useState(false);
+ const [modalLayout, setModalLayout] = useState( );
+
+ useEffect(() => {
+ handleServiceMapRequest(http, dslService, setServiceMap);
+ }, []);
+
+ useEffect(() => {
+ const serviceOptions = filters
+ .filter((f) => f.field === 'serviceName')
+ .map((f) => {
+ return { label: f.value };
+ });
+ const noDups = serviceOptions.filter((s, index) => {
+ return serviceOptions.findIndex((ser) => ser.label === s.label) === index;
+ });
+ setSelectedServices(noDups);
+ }, [filters]);
+
+ const addFilter = (filter: FilterType) => {
+ for (const addedFilter of filters) {
+ if (
+ addedFilter.field === filter.field &&
+ addedFilter.operator === filter.operator &&
+ addedFilter.value === filter.value
+ ) {
+ return;
+ }
+ }
+ const newFilters = [...filters, filter];
+ setFiltersWithStorage(newFilters);
+ };
+
+ const onServiceChange = (newServices: any) => {
+ const serviceFilters = newServices.map((option: OptionType) => {
+ return {
+ field: 'serviceName',
+ operator: 'is',
+ value: option.label,
+ inverted: false,
+ disabled: false,
+ };
+ });
+ const nonServiceFilters = filters.filter((f) => f.field !== 'serviceName');
+ setFiltersWithStorage([...nonServiceFilters, ...serviceFilters]);
+ };
+
+ const clearServices = () => {
+ const withoutServices = filters.filter((f) => f.field !== 'serviceName');
+ setFiltersWithStorage(withoutServices);
+ };
+
+ const services = Object.keys(serviceMap).map((service) => {
+ return { label: decodeURI(service) };
+ });
+
+ const onCancel = () => {
+ setIsModalVisible(false);
+ };
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onConfirm = () => {
+ clearServices();
+ closeModal();
+ };
+
+ const clearAllModal = () => {
+ setModalLayout(
+ getClearModal(
+ onCancel,
+ onConfirm,
+ 'Clear services & entities?',
+ 'This will clear all information in services & entities configuration.',
+ 'Clear all'
+ )
+ );
+ showModal();
+ };
+
+ return (
+
+
+
+
+ Services & entities{' '}
+
+ {selectedServices.length}
+
+
+
+
+
+ Select services & entities to include in this application
+
+ >
+ }
+ extraAction={
+
+ Clear all
+
+ }
+ onToggle={(isOpen) => {
+ setServicesOpen(isOpen);
+ }}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/components/config_components/trace_config.tsx b/dashboards-observability/public/components/application_analytics/components/config_components/trace_config.tsx
new file mode 100644
index 000000000..e0ff9a1bb
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/config_components/trace_config.tsx
@@ -0,0 +1,274 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import dateMath from '@elastic/datemath';
+import {
+ EuiAccordion,
+ EuiBadge,
+ EuiButton,
+ EuiComboBox,
+ EuiFormRow,
+ EuiOverlayMask,
+ EuiSpacer,
+ EuiText,
+} from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import React, { useEffect, useState } from 'react';
+import { FilterType } from 'public/components/trace_analytics/components/common/filters/filters';
+import { OptionType } from '../../../../../common/types/application_analytics';
+import { filtersToDsl } from '../../../trace_analytics/components/common/helper_functions';
+import { handleDashboardRequest } from '../../../trace_analytics/requests/dashboard_request_handler';
+import { AppAnalyticsComponentDeps } from '../../home';
+import { DashboardTable } from '../../../trace_analytics/components/dashboard/dashboard_table';
+import { getClearModal } from '../../helpers/modal_containers';
+
+interface TraceConfigProps extends AppAnalyticsComponentDeps {
+ dslService: DSLService;
+ selectedTraces: OptionType[];
+ setSelectedTraces: (traces: OptionType[]) => void;
+}
+
+export const TraceConfig = (props: TraceConfigProps) => {
+ const {
+ dslService,
+ query,
+ filters,
+ setFiltersWithStorage,
+ http,
+ startTime,
+ endTime,
+ selectedTraces,
+ setSelectedTraces,
+ } = props;
+ const [traceOpen, setTraceOpen] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [traceItems, setTraceItems] = useState([]);
+ const [traceOptions, setTraceOptions] = useState([]);
+ const [percentileMap, setPercentileMap] = useState<{ [traceGroup: string]: number[] }>({});
+ const [redirect, setRedirect] = useState(true);
+ const [isModalVisible, setIsModalVisible] = useState(false);
+ const [modalLayout, setModalLayout] = useState( );
+
+ useEffect(() => {
+ setLoading(true);
+ const timeFilterDSL = filtersToDsl([], '', startTime, endTime);
+ const latencyTrendStartTime = dateMath.parse(endTime)?.subtract(24, 'hours').toISOString()!;
+ const latencyTrendDSL = filtersToDsl(filters, query, latencyTrendStartTime, endTime);
+ handleDashboardRequest(
+ http,
+ dslService,
+ timeFilterDSL,
+ latencyTrendDSL,
+ traceItems,
+ setTraceItems,
+ setPercentileMap
+ ).then(() => setLoading(false));
+ setRedirect(false);
+ }, []);
+
+ useEffect(() => {
+ const toOptions = traceItems.map((item: any) => {
+ return { label: decodeURI(item.dashboard_trace_group_name) };
+ });
+ setTraceOptions(toOptions);
+ }, [traceItems]);
+
+ useEffect(() => {
+ const filteredOptions = filters
+ .filter((f) => f.field === 'traceGroup')
+ .map((f) => {
+ return { label: f.value };
+ });
+ const noDups = filteredOptions.filter((t, index) => {
+ return filteredOptions.findIndex((trace) => trace.label === t.label) === index;
+ });
+ setSelectedTraces(noDups);
+ }, [filters]);
+
+ const addFilter = (filter: FilterType) => {
+ for (const addedFilter of filters) {
+ if (
+ addedFilter.field === filter.field &&
+ addedFilter.operator === filter.operator &&
+ addedFilter.value === filter.value
+ ) {
+ const removed = filters.filter((fil) => fil.field !== addedFilter.field);
+ setFiltersWithStorage(removed);
+ return;
+ }
+ }
+ const newFilters = [...filters, filter];
+ setFiltersWithStorage(newFilters);
+ };
+
+ const onTraceChange = (newTraces: any) => {
+ const traceFilters = newTraces.map((option: OptionType) => {
+ return {
+ field: 'traceGroup',
+ operator: 'is',
+ value: option.label,
+ inverted: false,
+ disabled: false,
+ };
+ });
+ const nonTraceFilters = filters.filter((f) => f.field !== 'traceGroup');
+ setFiltersWithStorage([...nonTraceFilters, ...traceFilters]);
+ };
+
+ const onCreateTrace = (searchValue: string, flattenedOptions: any) => {
+ const normalizedSearchValue = searchValue.trim().toLowerCase();
+ if (!normalizedSearchValue) {
+ return;
+ }
+ const newTraceOption = {
+ label: searchValue,
+ };
+ const newTraceFilter = {
+ field: 'traceGroup',
+ operator: 'is',
+ value: searchValue,
+ inverted: false,
+ disabled: false,
+ };
+ // Create the option if it doesn't exist.
+ if (
+ flattenedOptions.findIndex(
+ (option: OptionType) => option.label.trim().toLowerCase() === normalizedSearchValue
+ ) === -1
+ ) {
+ setTraceOptions([...traceOptions, newTraceOption]);
+ }
+ // Select the option.
+ setFiltersWithStorage([...filters, newTraceFilter]);
+ };
+
+ const addPercentileFilter = (condition = 'gte', additionalFilters = [] as FilterType[]) => {
+ if (traceItems.length === 0 || Object.keys(percentileMap).length === 0) return;
+ for (let i = 0; i < filters.length; i++) {
+ if (filters[i].custom) {
+ const newFilter = JSON.parse(JSON.stringify(filters[i]));
+ newFilter.custom.query.bool.should.forEach((should: any) =>
+ should.bool.must.forEach((must: any) => {
+ const range = must?.range?.['traceGroupFields.durationInNanos'];
+ if (range) {
+ const duration = range.lt || range.lte || range.gt || range.gte;
+ if (duration || duration === 0) {
+ must.range['traceGroupFields.durationInNanos'] = {
+ [condition]: duration,
+ };
+ }
+ }
+ })
+ );
+ newFilter.value = condition === 'gte' ? '>= 95th' : '< 95th';
+ const newFilters = [...filters, ...additionalFilters];
+ newFilters.splice(i, 1, newFilter);
+ setFiltersWithStorage(newFilters);
+ return;
+ }
+ }
+ };
+
+ const clearTraces = () => {
+ const withoutTraces = filters.filter((f) => f.field !== 'traceGroup');
+ setFiltersWithStorage(withoutTraces);
+ };
+
+ const onCancel = () => {
+ setIsModalVisible(false);
+ };
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onConfirm = () => {
+ clearTraces();
+ closeModal();
+ };
+
+ const clearAllModal = () => {
+ setModalLayout(
+ getClearModal(
+ onCancel,
+ onConfirm,
+ 'Clear trace groups?',
+ 'This will clear all information in trace groups configuration.',
+ 'Clear all'
+ )
+ );
+ showModal();
+ };
+
+ return (
+
+
+
+
+ Trace groups{' '}
+ {selectedTraces.length}
+
+
+
+
+ Constrain your application to specific trace groups
+
+ >
+ }
+ extraAction={
+
+ Clear all
+
+ }
+ onToggle={(isOpen) => {
+ setTraceOpen(isOpen);
+ }}
+ paddingSize="l"
+ >
+
+
+
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/components/configuration.tsx b/dashboards-observability/public/components/application_analytics/components/configuration.tsx
new file mode 100644
index 000000000..8cb8080ff
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/configuration.tsx
@@ -0,0 +1,151 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiBreadcrumb,
+ EuiButton,
+ EuiCode,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHorizontalRule,
+ EuiLink,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiSelect,
+ EuiSelectOption,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import { ApplicationRequestType, ApplicationType } from 'common/types/application_analytics';
+import { last } from 'lodash';
+import React, { useState } from 'react';
+
+interface ConfigProps {
+ appId: string;
+ application: ApplicationType;
+ parentBreadcrumbs: EuiBreadcrumb[];
+ visWithAvailability: EuiSelectOption[];
+ switchToAvailability: () => void;
+ updateApp: (appId: string, updateAppData: Partial, type: string) => void;
+}
+
+export const Configuration = (props: ConfigProps) => {
+ const {
+ appId,
+ application,
+ parentBreadcrumbs,
+ visWithAvailability,
+ updateApp,
+ switchToAvailability,
+ } = props;
+ const [availabilityVisId, setAvailabilityVisId] = useState(
+ application.availability.availabilityVisId || ''
+ );
+
+ const onAvailabilityVisChange = (event: any) => {
+ setAvailabilityVisId(event.target.value);
+ updateApp(appId, { availabilityVisId: event.target.value }, 'editAvailability');
+ };
+
+ return (
+
+
+
+
+
+
+
+ Configuration details
+
+
+
+
+
+ {
+ window.location.assign(
+ `${last(parentBreadcrumbs)!.href}application_analytics/edit/${appId}`
+ );
+ }}
+ >
+ Edit
+
+
+
+
+
+
+
+
+
+
+ Log source
+
+
+
+ {application.baseQuery}
+
+
+
+
+ Services & entities
+
+
+
+
+ {application.servicesEntities.map((group) => (
+ {decodeURI(group)}
+ ))}
+
+
+
+
+
+ Trace groups
+
+
+
+
+ {application.traceGroups.map((group) => (
+ {decodeURI(group)}
+ ))}
+
+
+
+
+
+ Availability
+
+
+ {visWithAvailability.length > 0 ? (
+
+ ) : (
+ switchToAvailability()}
+ >
+ Set Availability
+
+ )}
+
+
+
+
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/components/create.tsx b/dashboards-observability/public/components/application_analytics/components/create.tsx
new file mode 100644
index 000000000..084d53b17
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/create.tsx
@@ -0,0 +1,278 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import {
+ EuiButton,
+ EuiFieldText,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiForm,
+ EuiFormRow,
+ EuiHorizontalRule,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiSpacer,
+ EuiTitle,
+ EuiToolTip,
+} from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import React, { ReactChild, useEffect, useState } from 'react';
+import PPLService from 'public/services/requests/ppl';
+import { last } from 'lodash';
+import { AppAnalyticsComponentDeps } from '../home';
+import { TraceConfig } from './config_components/trace_config';
+import { ServiceConfig } from './config_components/service_config';
+import { LogConfig } from './config_components/log_config';
+import { PPLReferenceFlyout } from '../../../components/common/helpers';
+import {
+ ApplicationRequestType,
+ ApplicationType,
+ OptionType,
+} from '../../../../common/types/application_analytics';
+import { fetchAppById } from '../helpers/utils';
+
+interface CreateAppProps extends AppAnalyticsComponentDeps {
+ dslService: DSLService;
+ pplService: PPLService;
+ setToasts: (title: string, color?: string, text?: ReactChild) => void;
+ createApp: (app: ApplicationRequestType, type: string) => void;
+ updateApp: (appId: string, updateAppData: Partial, type: string) => void;
+ clearStorage: () => void;
+ existingAppId: string;
+}
+
+export const CreateApp = (props: CreateAppProps) => {
+ const {
+ parentBreadcrumbs,
+ chrome,
+ http,
+ query,
+ name,
+ description,
+ pplService,
+ createApp,
+ updateApp,
+ setToasts,
+ setNameWithStorage,
+ setDescriptionWithStorage,
+ setQueryWithStorage,
+ setFilters,
+ clearStorage,
+ existingAppId,
+ } = props;
+ const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
+ const [selectedServices, setSelectedServices] = useState([]);
+ const [selectedTraces, setSelectedTraces] = useState([]);
+
+ const editMode = existingAppId !== 'undefined';
+ const [existingApp, setExistingApp] = useState({
+ id: existingAppId,
+ dateCreated: '',
+ dateModified: '',
+ name: '',
+ description: '',
+ baseQuery: '',
+ servicesEntities: [],
+ traceGroups: [],
+ panelId: '',
+ availability: { name: '', color: '', availabilityVisId: '' },
+ });
+
+ useEffect(() => {
+ chrome.setBreadcrumbs([
+ ...parentBreadcrumbs,
+ {
+ text: 'Application analytics',
+ href: '#/application_analytics',
+ },
+ {
+ text: editMode ? 'Edit' : 'Create',
+ href: `#/application_analytics/${editMode ? 'edit' : 'create'}`,
+ },
+ ]);
+ }, []);
+
+ useEffect(() => {
+ if (editMode && existingAppId) {
+ fetchAppById(
+ http,
+ pplService,
+ existingAppId,
+ setExistingApp,
+ setFilters,
+ () => {},
+ setToasts
+ );
+ }
+ }, [existingAppId]);
+
+ useEffect(() => {
+ if (editMode) {
+ setNameWithStorage(existingApp.name);
+ setDescriptionWithStorage(existingApp.description);
+ setQueryWithStorage(existingApp.baseQuery);
+ }
+ }, [existingApp]);
+
+ const closeFlyout = () => {
+ setIsFlyoutVisible(false);
+ };
+
+ let flyout;
+ if (isFlyoutVisible) {
+ flyout = ;
+ }
+
+ const isDisabled = !name || (!query && !selectedTraces.length && !selectedServices.length);
+
+ const missingField = (needLog: boolean) => {
+ let popoverContent = '';
+ if (isDisabled || (needLog && !query)) {
+ if (!name) {
+ popoverContent = 'Name is required.';
+ } else if (!query && !selectedServices.length && !selectedTraces.length) {
+ popoverContent = 'Provide at least one log source, service, entity or trace group.';
+ } else if (needLog && !query) {
+ popoverContent = 'Log source is required to set availability.';
+ }
+ return {popoverContent}
;
+ }
+ };
+
+ const onCreate = (type: string) => {
+ const appData = {
+ name,
+ description,
+ baseQuery: query,
+ servicesEntities: selectedServices.map((option) => option.label),
+ traceGroups: selectedTraces.map((option) => option.label),
+ panelId: '',
+ availabilityVisId: '',
+ };
+ createApp(appData, type);
+ };
+
+ const onUpdate = () => {
+ const appData = {
+ name,
+ description,
+ servicesEntities: selectedServices.map((option) => option.label),
+ traceGroups: selectedTraces.map((option) => option.label),
+ };
+ updateApp(existingAppId, appData, 'update');
+ };
+
+ const onCancel = () => {
+ clearStorage();
+ window.location.assign(`${last(parentBreadcrumbs)!.href}application_analytics`);
+ };
+
+ return (
+
+
+
+
+
+
+ {editMode ? 'Edit' : 'Create'} application
+
+
+
+
+
+
+
+ Application information
+
+
+
+
+
+
+ setNameWithStorage(e.target.value)}
+ />
+
+
+ setDescriptionWithStorage(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+ Composition
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+ onCreate('create')}
+ fill={editMode ? true : false}
+ >
+ {editMode ? 'Save' : 'Create'}
+
+
+
+ {editMode || (
+
+
+ onCreate('createSetAvailability')}
+ >
+ Create and Set Availability
+
+
+
+ )}
+
+
+
+ {flyout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/components/flyout_components/availability_info_flyout.tsx b/dashboards-observability/public/components/application_analytics/components/flyout_components/availability_info_flyout.tsx
new file mode 100644
index 000000000..86e668f41
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/flyout_components/availability_info_flyout.tsx
@@ -0,0 +1,62 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiFlyout,
+ EuiFlyoutHeader,
+ EuiTitle,
+ EuiFlyoutBody,
+ EuiText,
+ EuiCodeBlock,
+ EuiFlyoutFooter,
+ EuiButton,
+} from '@elastic/eui';
+import React from 'react';
+
+interface AvailabilityInfoFlyoutProps {
+ closeFlyout: () => void;
+}
+
+export function AvailabilityInfoFlyout(props: AvailabilityInfoFlyoutProps) {
+ const { closeFlyout } = props;
+
+ return (
+
+
+
+ Availability
+
+
+
+
+ Configure availability
+ Availability is the status of your application determined by availability levels set on a
+ time series metric. To create an availability level, you must configure the following:
+
+ color: The color of the availability badge on the home page
+ name: The text in the availability badge on the home page
+ expression: Comparison operator to determine the availability
+ value: Value to use when calculating availability
+
+ Configuring availability
+ By default, Application analytics shows results from the last 24 hours of your data. To
+ see data from a different timeframe, use the date and time selector.
+ Time series metric A time series metric is any visualization that has a query that
+ spans over a timestamp and is a bar/line chart. You can use the PPL language to define
+ arbitrary conditions on your logs to create a visualization over time.
+ Example
+
+ {'source = | ... | ... | stats ... by span(, 1h)'}
+
+ You can then choose Bar or Line in visualization
+ configurations to create a time series metric.
+
+
+
+ Close
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx b/dashboards-observability/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx
new file mode 100644
index 000000000..07a7e0a5a
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx
@@ -0,0 +1,141 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import _ from 'lodash';
+import {
+ EuiFlyout,
+ EuiFlyoutBody,
+ EuiFlyoutHeader,
+ EuiHorizontalRule,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import React, { useEffect, useMemo, useState } from 'react';
+import {
+ handleServiceMapRequest,
+ handleServiceViewRequest,
+} from '../../../../../public/components/trace_analytics/requests/services_request_handler';
+import { filtersToDsl } from '../../../../../public/components/trace_analytics/components/common/helper_functions';
+import { ServiceMap } from '../../../../../public/components/trace_analytics/components/services';
+import { ServiceObject } from '../../../../../public/components/trace_analytics/components/common/plots/service_map';
+import { SpanDetailTable } from '../../../../../public/components/trace_analytics/components/traces/span_detail_table';
+import { TraceAnalyticsComponentDeps } from '../../../../../public/components/trace_analytics/home';
+import { getListItem } from '../../helpers/utils';
+
+interface ServiceFlyoutProps extends TraceAnalyticsComponentDeps {
+ serviceName: string;
+ closeServiceFlyout: () => void;
+ openSpanFlyout: (spanId: string) => void;
+ setSelectedTab: (newTab: string) => void;
+}
+
+export function ServiceDetailFlyout(props: ServiceFlyoutProps) {
+ const {
+ serviceName,
+ http,
+ startTime,
+ endTime,
+ filters,
+ appConfigs,
+ query,
+ closeServiceFlyout,
+ openSpanFlyout,
+ } = props;
+ const [fields, setFields] = useState({});
+ const [serviceMap, setServiceMap] = useState({});
+ const [total, setTotal] = useState(0);
+ const [DSL, setDSL] = useState({});
+ const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
+ 'latency' | 'error_rate' | 'throughput'
+ >('latency');
+
+ const renderContent = useMemo(() => {
+ if (!serviceName) return '-';
+ const overviewList = [
+ getListItem('Name', serviceName),
+ getListItem(
+ 'Number of connected services',
+ fields.number_of_connected_services !== undefined ? fields.number_of_connected_services : 0
+ ),
+ getListItem(
+ 'Connected services',
+ fields.connected_services
+ ? fields.connected_services.reduce((prev: string, curr: string) => {
+ return [prev, ', ', curr];
+ })
+ : '-'
+ ),
+ getListItem(
+ 'Average latency (ms)',
+ fields.average_latency !== undefined ? fields.average_latency : '-'
+ ),
+ getListItem(
+ 'Error rate',
+ fields.error_rate !== undefined ? _.round(fields.error_rate, 2).toString() + '%' : '-'
+ ),
+ getListItem('Throughput', fields.throughput !== undefined ? fields.throughput : '-'),
+ getListItem('Traces', fields.traces === 0 || fields.traces ? fields.traces : '-'),
+ ];
+
+ return (
+ <>
+
+ Overview
+
+
+ {overviewList}
+
+
+
+
+
+
+ Spans
+ {total === 0 || total ? {` (${total})`} : null}
+
+
+
+ >
+ );
+ }, [serviceName, fields, serviceMap, DSL, serviceMapIdSelected]);
+
+ useEffect(() => {
+ const serviceDSL = filtersToDsl(filters, query, startTime, endTime, 'app', appConfigs);
+ handleServiceViewRequest(serviceName, http, serviceDSL, setFields);
+ handleServiceMapRequest(http, serviceDSL, setServiceMap, serviceName);
+ const spanDSL = filtersToDsl(filters, query, startTime, endTime, 'app', appConfigs);
+ spanDSL.query.bool.must.push({
+ term: {
+ serviceName,
+ },
+ });
+ setDSL(spanDSL);
+ }, [serviceName, startTime, endTime]);
+
+ return (
+
+
+
+ Service detail
+
+
+ {renderContent}
+
+ );
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_flyout.tsx b/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_flyout.tsx
new file mode 100644
index 000000000..ce687f306
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_flyout.tsx
@@ -0,0 +1,32 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
+import React from 'react';
+import { TraceAnalyticsComponentDeps } from '../../../../../public/components/trace_analytics/home';
+import { TraceDetailRender } from './trace_detail_render';
+
+interface TraceFlyoutProps extends TraceAnalyticsComponentDeps {
+ traceId: string;
+ closeTraceFlyout: () => void;
+ openSpanFlyout: (spanId: string) => void;
+}
+
+export function TraceDetailFlyout(props: TraceFlyoutProps) {
+ const { traceId, http, closeTraceFlyout, openSpanFlyout } = props;
+ const renderContent = (
+
+ );
+ return (
+
+
+
+ Trace detail
+
+
+ {renderContent}
+
+ );
+}
diff --git a/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx b/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx
new file mode 100644
index 000000000..34a91e01b
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx
@@ -0,0 +1,92 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiText, EuiSpacer, EuiHorizontalRule, EuiCodeBlock } from '@elastic/eui';
+import React, { useEffect, useMemo, useState } from 'react';
+import { ServiceBreakdownPanel } from '../../../trace_analytics/components/traces/service_breakdown_panel';
+import { SpanDetailPanel } from '../../../trace_analytics/components/traces/span_detail_panel';
+import {
+ handleTraceViewRequest,
+ handleServicesPieChartRequest,
+ handlePayloadRequest,
+} from '../../../trace_analytics/requests/traces_request_handler';
+import { HttpStart } from '../../../../../../../src/core/public';
+import { getListItem } from '../../helpers/utils';
+
+interface TraceDetailRenderProps {
+ traceId: string;
+ http: HttpStart;
+ openSpanFlyout: (spanId: string) => void;
+}
+
+export const TraceDetailRender = ({ traceId, http, openSpanFlyout }: TraceDetailRenderProps) => {
+ const [fields, setFields] = useState({});
+ const [serviceBreakdownData, setServiceBreakdownData] = useState([]);
+ const [payloadData, setPayloadData] = useState('');
+ const [colorMap, setColorMap] = useState({});
+
+ const renderContent = useMemo(() => {
+ if (!traceId) return <>>;
+ const overviewList = [
+ getListItem('Trace ID', traceId),
+ getListItem('Trace group name', fields.trace_group || '-'),
+ getListItem('Latency', fields.latency),
+ getListItem('Last updated', fields.last_updated),
+ getListItem(
+ 'Errors',
+ fields.error_count == null ? (
+ <>>
+ ) : fields.error_count > 0 ? (
+
+ Yes
+
+ ) : (
+ 'No'
+ )
+ ),
+ ];
+
+ return (
+ <>
+
+ Overview
+
+
+ {overviewList}
+
+
+
+
+
+
+
+
+
+ Payload
+
+
+ {payloadData.length > 0 ? (
+
+ {payloadData}
+
+ ) : null}
+ >
+ );
+ }, [traceId, fields, serviceBreakdownData, colorMap, payloadData]);
+
+ useEffect(() => {
+ handleTraceViewRequest(traceId, http, fields, setFields);
+ handleServicesPieChartRequest(traceId, http, setServiceBreakdownData, setColorMap);
+ handlePayloadRequest(traceId, http, payloadData, setPayloadData);
+ }, [traceId]);
+
+ return renderContent;
+};
diff --git a/dashboards-observability/public/components/application_analytics/helpers/modal_containers.tsx b/dashboards-observability/public/components/application_analytics/helpers/modal_containers.tsx
new file mode 100644
index 000000000..e9670bc3b
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/helpers/modal_containers.tsx
@@ -0,0 +1,37 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui';
+
+/* The file contains helper functions for modal layouts
+ * getClearModal - returns a confirm-modal with clear option
+ */
+
+export const getClearModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void,
+ title: string,
+ message: string,
+ confirmMessage?: string
+) => {
+ return (
+
+
+ {message}
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/application_analytics/helpers/utils.tsx b/dashboards-observability/public/components/application_analytics/helpers/utils.tsx
new file mode 100644
index 000000000..96e2d62be
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/helpers/utils.tsx
@@ -0,0 +1,330 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+
+import { EuiDescriptionList, EuiSelectOption, EuiSpacer, EuiText } from '@elastic/eui';
+import { ApplicationType, AvailabilityType } from 'common/types/application_analytics';
+import { FilterType } from 'public/components/trace_analytics/components/common/filters/filters';
+import React, { Dispatch, ReactChild } from 'react';
+import { batch } from 'react-redux';
+import PPLService from 'public/services/requests/ppl';
+import { preprocessQuery } from '../../../../common/utils/query_utils';
+import { SPAN_REGEX } from '../../../../common/constants/shared';
+import { fetchVisualizationById } from '../../../components/custom_panels/helpers/utils';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../common/constants/custom_panels';
+import { VisualizationType } from '../../../../common/types/custom_panels';
+import { NEW_SELECTED_QUERY_TAB, TAB_CREATED_TYPE } from '../../../../common/constants/explorer';
+import { APP_ANALYTICS_API_PREFIX } from '../../../../common/constants/application_analytics';
+import { HttpSetup } from '../../../../../../src/core/public';
+import { init as initFields, remove as removefields } from '../../explorer/slices/field_slice';
+import {
+ init as initVisualizationConfig,
+ reset as resetVisualizationConfig,
+} from '../../explorer/slices/viualization_config_slice';
+import {
+ init as initQuery,
+ remove as removeQuery,
+ changeQuery,
+} from '../../explorer/slices/query_slice';
+import {
+ init as initQueryResult,
+ remove as removeQueryResult,
+} from '../../explorer/slices/query_result_slice';
+import { addTab, removeTab } from '../../explorer/slices/query_tab_slice';
+
+// Name validation
+export const isNameValid = (name: string, existingNames: string[]) => {
+ const toast: string[] = [];
+ if (name.length >= 50) {
+ toast.push('Name must be less than 50 characters.');
+ }
+ if (name.trim().length === 0) {
+ toast.push('Name must not be empty.');
+ }
+ if (existingNames.includes(name)) {
+ toast.push('Name must be unique.');
+ }
+ return toast;
+};
+
+export const getListItem = (title: string, description: string | React.ReactElement) => {
+ const titleComponent = (
+
+ {title}
+
+ );
+
+ const descriptionComponent = (
+
+ {description}
+
+ );
+
+ return (
+
+
+
+
+ );
+};
+
+// Fetch application by id
+export const fetchAppById = async (
+ http: HttpSetup,
+ pplService: PPLService,
+ applicationId: string,
+ setApplication: (application: ApplicationType) => void,
+ setFilters: (filters: FilterType[]) => void,
+ setVisWithAvailability: (visList: EuiSelectOption[]) => void,
+ setToasts: (title: string, color?: string, text?: ReactChild) => void
+) => {
+ return http
+ .get(`${APP_ANALYTICS_API_PREFIX}/${applicationId}`)
+ .then(async (res: ApplicationType) => {
+ res.availability.availabilityVisId = (
+ await calculateAvailability(
+ http,
+ pplService,
+ res,
+ res.availability.availabilityVisId,
+ setVisWithAvailability
+ )
+ ).availabilityVisId;
+ setApplication(res);
+ const serviceFilters = res.servicesEntities.map((ser: string) => {
+ return {
+ field: 'serviceName',
+ operator: 'is',
+ value: ser,
+ inverted: false,
+ disabled: false,
+ };
+ });
+ const traceFilters = res.traceGroups.map((tra: string) => {
+ return {
+ field: 'traceGroup',
+ operator: 'is',
+ value: tra,
+ inverted: false,
+ disabled: false,
+ };
+ });
+ setFilters([...serviceFilters, ...traceFilters]);
+ })
+ .catch((err) => {
+ setToasts('Error occurred while fetching application', 'danger');
+ console.error(err);
+ });
+};
+
+// Remove tab data when closed
+export const removeTabData = (
+ dispatch: Dispatch,
+ TabIdToBeClosed: string,
+ newIdToFocus: string
+) => {
+ batch(() => {
+ dispatch(removeQuery({ tabId: TabIdToBeClosed }));
+ dispatch(removefields({ tabId: TabIdToBeClosed }));
+ dispatch(removeQueryResult({ tabId: TabIdToBeClosed }));
+ dispatch(resetVisualizationConfig({ tabId: TabIdToBeClosed }));
+ dispatch(
+ removeTab({
+ tabId: TabIdToBeClosed,
+ [NEW_SELECTED_QUERY_TAB]: newIdToFocus,
+ })
+ );
+ });
+};
+
+// Create a new tab and initialize its data
+export const initializeTabData = async (dispatch: Dispatch, tabId: string, where: string) => {
+ await batch(() => {
+ dispatch(initQuery({ tabId }));
+ dispatch(initQueryResult({ tabId }));
+ dispatch(initFields({ tabId }));
+ dispatch(addTab({ tabId }));
+ dispatch(initVisualizationConfig({ tabId }));
+ dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [TAB_CREATED_TYPE]: where,
+ },
+ })
+ );
+ });
+};
+
+export const fetchPanelsVizIdList = async (http: HttpSetup, appPanelId: string) => {
+ return await http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/panels/${appPanelId}`)
+ .then((res) => {
+ const visIds = res.operationalPanel.visualizations.map(
+ (viz: VisualizationType) => viz.savedVisualizationId
+ );
+ return visIds;
+ })
+ .catch((err) => {
+ console.error('Error occurred while fetching visualizations for panel', err);
+ return [];
+ });
+};
+
+export const calculateAvailability = async (
+ http: HttpSetup,
+ pplService: PPLService,
+ application: ApplicationType,
+ availabilityVisId: string,
+ setVisWithAvailability: (visList: EuiSelectOption[]) => void
+): Promise => {
+ let availability = { name: '', color: '', availabilityVisId: '' };
+ const panelId = application.panelId;
+ if (!panelId) return availability;
+ // Fetches saved visualizations associated to application's panel
+ // Order visualizations by most recently created
+ const savedVisualizationsIds = (await fetchPanelsVizIdList(http, panelId)).reverse();
+ if (!savedVisualizationsIds) return availability;
+ const visWithAvailability = [];
+ let availabilityFound = false;
+ for (let i = 0; i < savedVisualizationsIds.length; i++) {
+ const visualizationId = savedVisualizationsIds[i];
+ // Fetches data for visualization
+ const visData = await fetchVisualizationById(http, visualizationId, (value: string) =>
+ console.error(value)
+ );
+ // If there are levels, we get the current value
+ if (visData.user_configs.availabilityConfig?.hasOwnProperty('level')) {
+ // For every saved visualization with availability levels we push it to visWithAvailability
+ // This is used to populate the options in configuration
+ visWithAvailability.push({ value: visualizationId, text: visData.name });
+
+ const levels = visData.user_configs.availabilityConfig.level.reverse();
+ let currValue = Number.MIN_VALUE;
+ const finalQuery = preprocessQuery({
+ rawQuery: visData.query,
+ startTime: visData.selected_date_range.start,
+ endTime: visData.selected_date_range.end,
+ timeField: visData.timeField,
+ isLiveQuery: false,
+ });
+ await pplService
+ .fetch({
+ query: finalQuery,
+ format: 'viz',
+ })
+ .then((res) => {
+ const stat = res.metadata.fields.filter(
+ (field: { name: string; type: string }) => !field.name.match(SPAN_REGEX)
+ )[0].name;
+ const value = res.data[stat];
+ currValue = value[value.length - 1];
+ })
+ .catch((err) => {
+ console.error(err);
+ });
+ for (let j = 0; j < levels.length; j++) {
+ const level = levels[j];
+ // If there is an availiabilityVisId selected we only want to compute availability based on that
+ if (availabilityVisId ? availabilityVisId === visualizationId : true) {
+ if (level.value !== null) {
+ if (currValue === null) {
+ availability = {
+ name: '',
+ color: 'null',
+ availabilityVisId: '',
+ };
+ } else {
+ if (!availabilityFound) {
+ const expression = level.expression;
+ switch (expression) {
+ case '≥':
+ if (currValue >= parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ case '≤':
+ if (currValue <= parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ case '>':
+ if (currValue > parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ case '<':
+ if (currValue < parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ case '=':
+ if (currValue === parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ case '≠':
+ if (currValue !== parseFloat(level.value)) {
+ availability = {
+ name: level.name,
+ color: level.color,
+ availabilityVisId: visualizationId,
+ };
+ availabilityFound = true;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ setVisWithAvailability(visWithAvailability);
+ if (!availabilityFound && visWithAvailability.length > 0) {
+ return { name: '', color: 'undefined', availabilityVisId: '' };
+ }
+ return availability;
+};
diff --git a/dashboards-observability/public/components/application_analytics/home.tsx b/dashboards-observability/public/components/application_analytics/home.tsx
new file mode 100644
index 000000000..95ab3d978
--- /dev/null
+++ b/dashboards-observability/public/components/application_analytics/home.tsx
@@ -0,0 +1,445 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable no-console */
+
+import React, { ReactChild, useEffect, useState } from 'react';
+import { Route, RouteComponentProps, Switch } from 'react-router-dom';
+import DSLService from 'public/services/requests/dsl';
+import PPLService from 'public/services/requests/ppl';
+import SavedObjects from 'public/services/saved_objects/event_analytics/saved_objects';
+import TimestampUtils from 'public/services/timestamp/timestamp';
+import { EuiGlobalToastList, EuiLink } from '@elastic/eui';
+import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
+import { isEmpty, last } from 'lodash';
+import { useDispatch } from 'react-redux';
+import { AppTable } from './components/app_table';
+import { Application } from './components/application';
+import { CreateApp } from './components/create';
+import { TraceAnalyticsComponentDeps, TraceAnalyticsCoreDeps } from '../trace_analytics/home';
+import { FilterType } from '../trace_analytics/components/common/filters/filters';
+import { handleIndicesExistRequest } from '../trace_analytics/requests/request_handler';
+import { ObservabilitySideBar } from '../common/side_nav';
+import { NotificationsStart } from '../../../../../src/core/public';
+import { APP_ANALYTICS_API_PREFIX } from '../../../common/constants/application_analytics';
+import {
+ ApplicationRequestType,
+ ApplicationType,
+} from '../../../common/types/application_analytics';
+import {
+ calculateAvailability,
+ fetchPanelsVizIdList,
+ isNameValid,
+ removeTabData,
+} from './helpers/utils';
+import {
+ CUSTOM_PANELS_API_PREFIX,
+ CUSTOM_PANELS_DOCUMENTATION_URL,
+} from '../../../common/constants/custom_panels';
+
+export type AppAnalyticsCoreDeps = TraceAnalyticsCoreDeps;
+
+interface HomeProps extends RouteComponentProps, AppAnalyticsCoreDeps {
+ pplService: PPLService;
+ dslService: DSLService;
+ savedObjects: SavedObjects;
+ timestampUtils: TimestampUtils;
+ notifications: NotificationsStart;
+}
+
+export interface AppAnalyticsComponentDeps extends TraceAnalyticsComponentDeps {
+ name: string;
+ description: string;
+ setNameWithStorage: (newName: string) => void;
+ setDescriptionWithStorage: (newDescription: string) => void;
+ setQueryWithStorage: (newQuery: string) => void;
+ setFiltersWithStorage: (newFilters: FilterType[]) => void;
+ setAppConfigs: (newAppConfigs: FilterType[]) => void;
+}
+
+export const Home = (props: HomeProps) => {
+ const {
+ pplService,
+ dslService,
+ timestampUtils,
+ savedObjects,
+ parentBreadcrumbs,
+ http,
+ chrome,
+ notifications,
+ } = props;
+ const [triggerSwitchToEvent, setTriggerSwitchToEvent] = useState(0);
+ const dispatch = useDispatch();
+ const [applicationList, setApplicationList] = useState([]);
+ const [toasts, setToasts] = useState([]);
+ const [indicesExist, setIndicesExist] = useState(true);
+ const [appConfigs, setAppConfigs] = useState([]);
+ const storedFilters = sessionStorage.getItem('AppAnalyticsFilters');
+ const [filters, setFilters] = useState(
+ storedFilters ? JSON.parse(storedFilters) : []
+ );
+ const [name, setName] = useState(sessionStorage.getItem('AppAnalyticsName') || '');
+ const [description, setDescription] = useState(
+ sessionStorage.getItem('AppAnalyticsDescription') || ''
+ );
+ const [query, setQuery] = useState(sessionStorage.getItem('AppAnalyticsQuery') || '');
+ const [startTime, setStartTime] = useState(
+ sessionStorage.getItem('AppAnalyticsStartTime') || 'now-24h'
+ );
+ const [endTime, setEndTime] = useState(
+ sessionStorage.getItem('AppAnalyticsEndTime') || 'now'
+ );
+
+ // Setting state with storage to save input when user refreshes page
+ const setFiltersWithStorage = (newFilters: FilterType[]) => {
+ setFilters(newFilters);
+ sessionStorage.setItem('AppAnalyticsFilters', JSON.stringify(newFilters));
+ };
+ const setNameWithStorage = (newName: string) => {
+ setName(newName);
+ sessionStorage.setItem('AppAnalyticsName', newName);
+ };
+ const setDescriptionWithStorage = (newDescription: string) => {
+ setDescription(newDescription);
+ sessionStorage.setItem('AppAnalyticsDescription', newDescription);
+ };
+ const setQueryWithStorage = (newQuery: string) => {
+ setQuery(newQuery);
+ sessionStorage.setItem('AppAnalyticsQuery', newQuery);
+ };
+
+ useEffect(() => {
+ handleIndicesExistRequest(http, setIndicesExist);
+ }, []);
+
+ const commonProps: AppAnalyticsComponentDeps = {
+ parentBreadcrumbs,
+ http,
+ chrome,
+ name,
+ setNameWithStorage,
+ description,
+ setDescriptionWithStorage,
+ query,
+ setQuery,
+ setQueryWithStorage,
+ appConfigs,
+ setAppConfigs,
+ filters,
+ setFilters,
+ setFiltersWithStorage,
+ startTime,
+ setStartTime,
+ endTime,
+ setEndTime,
+ indicesExist,
+ };
+
+ const setToast = (title: string, color = 'success', text?: ReactChild) => {
+ if (!text) text = '';
+ setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]);
+ };
+
+ const clearStorage = () => {
+ setNameWithStorage('');
+ setDescriptionWithStorage('');
+ setFiltersWithStorage([]);
+ setQueryWithStorage('');
+ };
+
+ const moveToApp = (id: string, type: string) => {
+ window.location.assign(`${last(parentBreadcrumbs)!.href}application_analytics/${id}`);
+ if (type === 'createSetAvailability') {
+ setTriggerSwitchToEvent(2);
+ }
+ };
+
+ const createPanelForApp = (applicationId: string, appName: string, type: string) => {
+ return http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels`, {
+ body: JSON.stringify({
+ panelName: `${appName}'s Panel`,
+ applicationId,
+ }),
+ })
+ .then((res) => {
+ updateApp(applicationId, { panelId: res.newPanelId }, type);
+ })
+ .catch((err) => {
+ setToast(
+ 'Please ask your administrator to enable Operational Panels for you.',
+ 'danger',
+
+ Documentation
+
+ );
+ console.error(err);
+ });
+ };
+
+ const deletePanelForApp = (appPanelId: string) => {
+ const concatList = [appPanelId].toString();
+ return http.delete(`${CUSTOM_PANELS_API_PREFIX}/panelList/` + concatList).catch((err) => {
+ setToast(
+ 'Error occurred while deleting Operational Panels, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ const deleteSavedVisualizationsForPanel = async (appPanelId: string) => {
+ const savedVizIdsToDelete = await fetchPanelsVizIdList(http, appPanelId);
+ if (!isEmpty(savedVizIdsToDelete)) {
+ savedObjects
+ .deleteSavedObjectsList({ objectIdList: savedVizIdsToDelete })
+ .then((res) => {
+ deletePanelForApp(appPanelId);
+ })
+ .catch((err) => {
+ setToast('Error occurred while deleting Saved Visualizations', 'danger');
+ console.error(err);
+ });
+ }
+ };
+
+ // Fetches all existing applications
+ const fetchApps = () => {
+ return http
+ .get(`${APP_ANALYTICS_API_PREFIX}/`)
+ .then(async (res) => {
+ // Want to calculate availability going down the table
+ const availabilityVisIdStore: Record = {};
+ for (let i = 0; i < res.data.length; i++) {
+ availabilityVisIdStore[res.data[i].id] = res.data[i].availability.availabilityVisId;
+ res.data[i].availability = { name: '', color: 'loading', availabilityVisId: '' };
+ }
+ setApplicationList(res.data);
+ for (let i = res.data.length - 1; i > -1; i--) {
+ res.data[i].availability = await calculateAvailability(
+ http,
+ pplService,
+ res.data[i],
+ availabilityVisIdStore[res.data[i].id],
+ () => {}
+ );
+ // Need to set state with new object to trigger re-render
+ setApplicationList([
+ ...res.data.filter((app: ApplicationType) => app.id !== res.data[i].id),
+ res.data[i],
+ ]);
+ }
+ })
+ .catch((err) => {
+ setToast('Error occurred while fetching applications', 'danger');
+ console.error(err);
+ });
+ };
+
+ // Create a new application
+ const createApp = (application: ApplicationRequestType, type: string) => {
+ const toast = isNameValid(
+ application.name,
+ applicationList.map((obj) => obj.name)
+ );
+ if (toast.length > 0) {
+ setToast(toast.join(', '), 'danger');
+ return;
+ }
+
+ const requestBody = {
+ name: application.name,
+ description: application.description || '',
+ baseQuery: application.baseQuery,
+ servicesEntities: application.servicesEntities,
+ traceGroups: application.traceGroups,
+ availabilityVisId: '',
+ };
+
+ return http
+ .post(`${APP_ANALYTICS_API_PREFIX}/`, {
+ body: JSON.stringify(requestBody),
+ })
+ .then(async (res) => {
+ createPanelForApp(res.newAppId, application.name, type);
+ setToast(`Application "${application.name}" successfully created!`);
+ clearStorage();
+ })
+ .catch((err) => {
+ setToast(`Error occurred while creating new application "${application.name}"`, 'danger');
+ console.error(err);
+ });
+ };
+
+ // Rename an existing application
+ const renameApp = (newAppName: string, appId: string) => {
+ const toast = isNameValid(
+ newAppName,
+ applicationList.map((obj) => obj.name)
+ );
+ if (toast.length > 0) {
+ setToast(toast.join(', '), 'danger');
+ return;
+ }
+
+ const requestBody = {
+ appId,
+ name: newAppName,
+ };
+
+ return http
+ .put(`${APP_ANALYTICS_API_PREFIX}/rename`, {
+ body: JSON.stringify(requestBody),
+ })
+ .then((res) => {
+ setApplicationList((prevApplicationList) => {
+ const newApplicationData = [...prevApplicationList];
+ const renamedApplication = newApplicationData.find(
+ (application) => application.id === appId
+ );
+ if (renamedApplication) renamedApplication.name = newAppName;
+ return newApplicationData;
+ });
+ setToast(`Application successfully renamed to "${newAppName}"`);
+ })
+ .catch((err) => {
+ setToast('Error occurred while renaming application', 'danger');
+ console.error(err);
+ });
+ };
+
+ // Update existing application
+ const updateApp = (
+ appId: string,
+ updateAppData: Partial,
+ type: string
+ ) => {
+ const requestBody = {
+ appId,
+ updateBody: updateAppData,
+ };
+
+ return http
+ .put(`${APP_ANALYTICS_API_PREFIX}/`, {
+ body: JSON.stringify(requestBody),
+ })
+ .then((res) => {
+ if (type === 'update') {
+ setToast('Application successfully updated.');
+ clearStorage();
+ moveToApp(res.updatedAppId, type);
+ }
+ if (type.startsWith('create')) {
+ moveToApp(res.updatedAppId, type);
+ }
+ })
+ .catch((err) => {
+ setToast('Error occurred while updating application', 'danger');
+ console.error(err);
+ });
+ };
+
+ // Delete existing applications
+ const deleteApp = (appList: string[], panelList: string[], toastMessage?: string) => {
+ return http
+ .delete(`${APP_ANALYTICS_API_PREFIX}/${appList.join(',')}`)
+ .then((res) => {
+ setApplicationList((prevApplicationList) => {
+ return prevApplicationList.filter((app) => !appList.includes(app.id));
+ });
+
+ for (let i = 0; i < appList.length; i++) {
+ removeTabData(dispatch, appList[i], '');
+ }
+
+ for (let i = 0; i < panelList.length; i++) {
+ deleteSavedVisualizationsForPanel(panelList[i]);
+ }
+
+ const message =
+ toastMessage || `Application${appList.length > 1 ? 's' : ''} successfully deleted!`;
+ setToast(message);
+ return res;
+ })
+ .catch((err: any) => {
+ setToast('Error occured while deleting application', 'danger');
+ console.error(err);
+ });
+ };
+
+ const callback = (childFunc: () => void) => {
+ if (childFunc && triggerSwitchToEvent > 0) {
+ childFunc();
+ setTriggerSwitchToEvent(triggerSwitchToEvent - 1);
+ }
+ };
+
+ return (
+
+
{
+ setToasts(toasts.filter((toast) => toast.id !== removedToast.id));
+ }}
+ toastLifeTimeMs={6000}
+ />
+
+ (
+
+
+
+ )}
+ />
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/debounced_component/debounced_component.tsx b/dashboards-observability/public/components/common/debounced_component/debounced_component.tsx
new file mode 100644
index 000000000..710c16c9c
--- /dev/null
+++ b/dashboards-observability/public/components/common/debounced_component/debounced_component.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useMemo, useEffect, memo, FunctionComponent } from 'react';
+import { debounce } from 'lodash';
+
+/**
+ * debouncedComponent wraps the specified React component, returning a component which
+ * only renders once there is a pause in props changes for at least `delay` milliseconds.
+ * During the debounce phase, it will return the previously rendered value.
+ */
+export function debouncedComponent(component: FunctionComponent, delay = 256) {
+ const MemoizedComponent = (memo(component) as unknown) as FunctionComponent;
+
+ return (props: TProps) => {
+ const [cachedProps, setCachedProps] = useState(props);
+ const debouncePropsChange = useMemo(() => debounce(setCachedProps, delay), [setCachedProps]);
+
+ // cancel debounced prop change if component has been unmounted in the meantime
+ useEffect(() => () => debouncePropsChange.cancel(), [debouncePropsChange]);
+ debouncePropsChange(props);
+
+ return React.createElement(MemoizedComponent, cachedProps);
+ };
+}
diff --git a/dashboards-observability/public/components/common/debounced_component/index.ts b/dashboards-observability/public/components/common/debounced_component/index.ts
new file mode 100644
index 000000000..aa1308791
--- /dev/null
+++ b/dashboards-observability/public/components/common/debounced_component/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './debounced_component';
diff --git a/dashboards-observability/public/components/common/field_button/field_button.scss b/dashboards-observability/public/components/common/field_button/field_button.scss
new file mode 100644
index 000000000..8ae66b433
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_button/field_button.scss
@@ -0,0 +1,80 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.osdFieldButton {
+ @include euiFontSizeS;
+ border-radius: $euiBorderRadius;
+ margin-bottom: $euiSizeXS;
+ display: flex;
+ align-items: center;
+ transition: box-shadow $euiAnimSpeedFast $euiAnimSlightResistance,
+ background-color $euiAnimSpeedFast $euiAnimSlightResistance; // sass-lint:disable-line indentation
+
+ &:focus-within,
+ &-isActive {
+ @include euiFocusRing;
+ }
+}
+
+.osdFieldButton--isDraggable {
+ background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade);
+
+ &:hover,
+ &:focus,
+ &:focus-within {
+ @include euiBottomShadowMedium;
+ border-radius: $euiBorderRadius;
+ z-index: 2;
+ }
+
+ .osdFieldButton__button {
+ &:hover,
+ &:focus {
+ cursor: grab;
+ }
+ }
+}
+
+.osdFieldButton__button {
+ flex-grow: 1;
+ text-align: left;
+ padding: $euiSizeS;
+ display: flex;
+ align-items: flex-start;
+}
+
+.osdFieldButton__fieldIcon {
+ flex-shrink: 0;
+ line-height: 0;
+ margin-right: $euiSizeS;
+}
+
+.osdFieldButton__name {
+ flex-grow: 1;
+ word-break: break-word;
+}
+
+.osdFieldButton__infoIcon {
+ flex-shrink: 0;
+ margin-left: $euiSizeXS;
+}
+
+.osdFieldButton__fieldAction {
+ margin-right: $euiSizeS;
+}
+
+// Reduce text size and spacing for the small size
+.osdFieldButton--small {
+ font-size: $euiFontSizeXS;
+
+ .osdFieldButton__button {
+ padding: $euiSizeXS;
+ }
+
+ .osdFieldButton__fieldIcon,
+ .osdFieldButton__fieldAction {
+ margin-right: $euiSizeXS;
+ }
+}
diff --git a/dashboards-observability/public/components/common/field_button/field_button.tsx b/dashboards-observability/public/components/common/field_button/field_button.tsx
new file mode 100644
index 000000000..5ceac9875
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_button/field_button.tsx
@@ -0,0 +1,122 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './field_button.scss';
+import classNames from 'classnames';
+import React, { ReactNode, HTMLAttributes, ButtonHTMLAttributes } from 'react';
+import { CommonProps } from '@elastic/eui';
+
+export interface FieldButtonProps extends HTMLAttributes {
+ /**
+ * Label for the button
+ */
+ fieldName: ReactNode;
+ /**
+ * Icon representing the field type.
+ * Recommend using FieldIcon
+ */
+ fieldIcon?: ReactNode;
+ /**
+ * An optional node to place inside and at the end of the
+ */
+ fieldInfoIcon?: ReactNode;
+ /**
+ * An optional node to place outside of and to the right of the
+ */
+ fieldAction?: ReactNode;
+ /**
+ * Adds a forced focus ring to the whole component
+ */
+ isActive?: boolean;
+ /**
+ * Styles the component differently to indicate it is draggable
+ */
+ isDraggable?: boolean;
+ /**
+ * Use the small size in condensed areas
+ */
+ size?: ButtonSize;
+ className?: string;
+ /**
+ * The component will render a `` when provided an `onClick`
+ */
+ onClick?: () => void;
+ /**
+ * Applies to the inner `` or ``
+ */
+ dataTestSubj?: string;
+ /**
+ * Pass more button props to the `
` element
+ */
+ buttonProps?: ButtonHTMLAttributes & CommonProps;
+}
+
+const sizeToClassNameMap = {
+ s: 'osdFieldButton--small',
+ m: null,
+} as const;
+
+export type ButtonSize = keyof typeof sizeToClassNameMap;
+
+export const SIZES = Object.keys(sizeToClassNameMap) as ButtonSize[];
+
+export function FieldButton({
+ size = 'm',
+ isActive = false,
+ fieldIcon,
+ fieldName,
+ fieldInfoIcon,
+ fieldAction,
+ className,
+ isDraggable = false,
+ onClick,
+ dataTestSubj,
+ buttonProps,
+ ...rest
+}: FieldButtonProps) {
+ const classes = classNames(
+ 'osdFieldButton',
+ size ? sizeToClassNameMap[size] : null,
+ { 'osdFieldButton-isActive': isActive },
+ { 'osdFieldButton--isDraggable': isDraggable },
+ className
+ );
+
+ const contentClasses = classNames('osd-resetFocusState', 'osdFieldButton__button');
+
+ const innerContent = (
+ <>
+ {fieldIcon && {fieldIcon} }
+ {fieldName && {fieldName} }
+ {fieldInfoIcon && {fieldInfoIcon}
}
+ >
+ );
+
+ return (
+
+ {onClick ? (
+
{
+ if (e.type === 'click') {
+ e.currentTarget.focus();
+ }
+ onClick();
+ }}
+ data-test-subj={dataTestSubj}
+ className={contentClasses}
+ {...buttonProps}
+ >
+ {innerContent}
+
+ ) : (
+
+ {innerContent}
+
+ )}
+
+ {fieldAction &&
{fieldAction}
}
+
+ );
+}
diff --git a/dashboards-observability/public/components/common/field_button/index.ts b/dashboards-observability/public/components/common/field_button/index.ts
new file mode 100644
index 000000000..70274f800
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_button/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './field_button';
diff --git a/dashboards-observability/public/components/common/field_icon/field_icon.tsx b/dashboards-observability/public/components/common/field_icon/field_icon.tsx
new file mode 100644
index 000000000..a63dfe5ad
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_icon/field_icon.tsx
@@ -0,0 +1,71 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import classNames from 'classnames';
+import { EuiToken, EuiTokenProps } from '@elastic/eui';
+
+export interface FieldIconProps extends Omit {
+ type:
+ | 'boolean'
+ | 'conflict'
+ | 'date'
+ | 'geo_point'
+ | 'geo_shape'
+ | 'ip'
+ | 'murmur3'
+ | 'number'
+ | '_source'
+ | 'string'
+ | string
+ | 'nested';
+ label?: string;
+ scripted?: boolean;
+}
+
+// defaultIcon => a unknown datatype
+const defaultIcon = { iconType: 'questionInCircle', color: 'gray' };
+
+export const typeToEuiIconMap: Partial> = {
+ boolean: { iconType: 'tokenBoolean' },
+ // icon for an index pattern mapping conflict in discover
+ conflict: { iconType: 'alert', color: 'euiVisColor9' },
+ date: { iconType: 'tokenDate' },
+ geo_point: { iconType: 'tokenGeo' },
+ geo_shape: { iconType: 'tokenGeo' },
+ ip: { iconType: 'tokenIP' },
+ // is a plugin's data type https://www.elastic.co/guide/en/elasticsearch/plugins/current/mapper-murmur3-usage.html
+ murmur3: { iconType: 'tokenFile' },
+ number: { iconType: 'tokenNumber' },
+ _source: { iconType: 'editorCodeBlock', color: 'gray' },
+ string: { iconType: 'tokenString' },
+ nested: { iconType: 'tokenNested' },
+};
+
+/**
+ * Field token icon used across the app
+ */
+export function FieldIcon({
+ type,
+ label,
+ size = 's',
+ scripted,
+ className,
+ ...rest
+}: FieldIconProps) {
+ const token = typeToEuiIconMap[type] || defaultIcon;
+
+ return (
+
+ );
+}
diff --git a/dashboards-observability/public/components/common/field_icon/index.ts b/dashboards-observability/public/components/common/field_icon/index.ts
new file mode 100644
index 000000000..87023615e
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_icon/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './field_icon';
diff --git a/dashboards-observability/public/components/common/field_name/field_name.tsx b/dashboards-observability/public/components/common/field_name/field_name.tsx
new file mode 100644
index 000000000..b7ea2a592
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_name/field_name.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
+
+// import { FieldIcon, FieldIconProps } from '../../../../../kibana_react/public';
+// import { shortenDottedString } from '../../helpers';
+import { getFieldTypeName } from './field_type_name';
+
+// properties fieldType and fieldName are provided in osd_doc_view
+// this should be changed when both components are deangularized
+interface Props {
+ fieldName: string;
+ fieldType: string;
+ useShortDots?: boolean;
+ // fieldIconProps?: Omit;
+ scripted?: boolean;
+}
+
+export function FieldName({
+ fieldName,
+ fieldType,
+ useShortDots,
+ // fieldIconProps,
+ scripted = false,
+}: Props) {
+ const typeName = getFieldTypeName(fieldType);
+ // const displayName = useShortDots ? shortenDottedString(fieldName) : fieldName;
+ const displayName = fieldName;
+
+ return (
+
+ {/*
+
+ */}
+
+
+ {displayName}
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/common/field_name/field_type_name.ts b/dashboards-observability/public/components/common/field_name/field_type_name.ts
new file mode 100644
index 000000000..f44eeb79c
--- /dev/null
+++ b/dashboards-observability/public/components/common/field_name/field_type_name.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { i18n } from '@osd/i18n';
+
+export function getFieldTypeName(type: string) {
+ switch (type) {
+ case 'boolean':
+ return i18n.translate('discover.fieldNameIcons.booleanAriaLabel', {
+ defaultMessage: 'Boolean field',
+ });
+ case 'conflict':
+ return i18n.translate('discover.fieldNameIcons.conflictFieldAriaLabel', {
+ defaultMessage: 'Conflicting field',
+ });
+ case 'date':
+ return i18n.translate('discover.fieldNameIcons.dateFieldAriaLabel', {
+ defaultMessage: 'Date field',
+ });
+ case 'geo_point':
+ return i18n.translate('discover.fieldNameIcons.geoPointFieldAriaLabel', {
+ defaultMessage: 'Geo point field',
+ });
+ case 'geo_shape':
+ return i18n.translate('discover.fieldNameIcons.geoShapeFieldAriaLabel', {
+ defaultMessage: 'Geo shape field',
+ });
+ case 'ip':
+ return i18n.translate('discover.fieldNameIcons.ipAddressFieldAriaLabel', {
+ defaultMessage: 'IP address field',
+ });
+ case 'murmur3':
+ return i18n.translate('discover.fieldNameIcons.murmur3FieldAriaLabel', {
+ defaultMessage: 'Murmur3 field',
+ });
+ case 'number':
+ return i18n.translate('discover.fieldNameIcons.numberFieldAriaLabel', {
+ defaultMessage: 'Number field',
+ });
+ case 'source':
+ // Note that this type is currently not provided, type for _source is undefined
+ return i18n.translate('discover.fieldNameIcons.sourceFieldAriaLabel', {
+ defaultMessage: 'Source field',
+ });
+ case 'string':
+ return i18n.translate('discover.fieldNameIcons.stringFieldAriaLabel', {
+ defaultMessage: 'String field',
+ });
+ case 'nested':
+ return i18n.translate('discover.fieldNameIcons.nestedFieldAriaLabel', {
+ defaultMessage: 'Nested field',
+ });
+ default:
+ return i18n.translate('discover.fieldNameIcons.unknownFieldAriaLabel', {
+ defaultMessage: 'Unknown field',
+ });
+ }
+}
diff --git a/dashboards-observability/public/components/common/flyout_containers/flyout_containers.tsx b/dashboards-observability/public/components/common/flyout_containers/flyout_containers.tsx
new file mode 100644
index 000000000..182a811aa
--- /dev/null
+++ b/dashboards-observability/public/components/common/flyout_containers/flyout_containers.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiFlyout } from '@elastic/eui';
+import React from 'react';
+
+/*
+ * "FlyoutContainers" component used to create flyouts
+ *
+ * Props taken in as params are:
+ * flyoutHeader - header JSX element of flyout
+ * flyoutBody - body JSX element of flyout
+ * flyoutFooter - footer JSX element of flyout
+ * ariaLabel - aria-label for focus of flyout
+ */
+
+type Props = {
+ closeFlyout: () => void;
+ flyoutHeader: JSX.Element;
+ flyoutBody: JSX.Element;
+ flyoutFooter: JSX.Element;
+ ariaLabel: string;
+ size?: string;
+};
+
+export const FlyoutContainers = ({
+ closeFlyout,
+ flyoutHeader,
+ flyoutBody,
+ flyoutFooter,
+ ariaLabel,
+ size,
+}: Props) => {
+ return (
+
+ closeFlyout()}
+ size={size ? size : 'm'}
+ aria-labelledby={ariaLabel}
+ >
+ {flyoutHeader}
+ {flyoutBody}
+ {flyoutFooter}
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/flyout_containers/index.ts b/dashboards-observability/public/components/common/flyout_containers/index.ts
new file mode 100644
index 000000000..bff974193
--- /dev/null
+++ b/dashboards-observability/public/components/common/flyout_containers/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { FlyoutContainers } from './flyout_containers';
diff --git a/dashboards-observability/public/components/common/helpers/add_sample_modal.tsx b/dashboards-observability/public/components/common/helpers/add_sample_modal.tsx
new file mode 100644
index 000000000..d027b7354
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/add_sample_modal.tsx
@@ -0,0 +1,32 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui';
+
+export const getSampleDataModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void
+) => {
+ return (
+
+
+
+ Do you want to add sample data? This will also add Dashboards sample flights and logs
+ data if they have not been added.
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/helpers/delete_modal.tsx b/dashboards-observability/public/components/common/helpers/delete_modal.tsx
new file mode 100644
index 000000000..9bf80ec1f
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/delete_modal.tsx
@@ -0,0 +1,79 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import {
+ EuiOverlayMask,
+ EuiModal,
+ EuiButton,
+ EuiButtonEmpty,
+ EuiFieldText,
+ EuiForm,
+ EuiFormRow,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiSpacer,
+ EuiText,
+} from '@elastic/eui';
+
+export const DeleteModal = ({
+ onCancel,
+ onConfirm,
+ title,
+ message,
+}: {
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void;
+ onConfirm: (event?: React.MouseEvent) => void;
+ title: string;
+ message: string;
+}) => {
+ const [value, setValue] = useState('');
+ const onChange = (e: React.ChangeEvent) => {
+ setValue(e.target.value);
+ };
+ return (
+
+
+
+ {title}
+
+
+
+ {message}
+ The action cannot be undone.
+
+
+
+ onChange(e)}
+ data-test-subj="popoverModal__deleteTextInput"
+ />
+
+
+
+
+
+ Cancel
+ onConfirm()}
+ color="danger"
+ fill
+ disabled={value !== 'delete'}
+ data-test-subj="popoverModal__deleteButton"
+ >
+ Delete
+
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/helpers/format_number_with_commas.ts b/dashboards-observability/public/components/common/helpers/format_number_with_commas.ts
new file mode 100644
index 000000000..861f62ad1
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/format_number_with_commas.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+const COMMA_SEPARATOR_RE = /(\d)(?=(\d{3})+(?!\d))/g;
+
+/**
+ * Converts a number to a string and adds commas
+ * as thousands separators
+ */
+export const formatNumWithCommas = (input: number) =>
+ String(input).replace(COMMA_SEPARATOR_RE, '$1,');
diff --git a/dashboards-observability/public/components/common/helpers/index.ts b/dashboards-observability/public/components/common/helpers/index.ts
new file mode 100644
index 000000000..6aa2e9527
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { formatNumWithCommas } from './format_number_with_commas';
+export { PPLReferenceFlyout } from './ppl_reference_flyout';
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/dedup.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/dedup.ts
new file mode 100644
index 000000000..2de86921b
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/dedup.ts
@@ -0,0 +1,114 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const dedupCmd = `## dedup
+---
+
+### Description
+
+Using \'dedup\' command to remove identical document defined by field from
+the search result.
+
+### Syntax
+
+dedup \[int\] <field-list> \[keepempty=<bool>\]
+\[consecutive=<bool>\]
+
+- int: optional. The \'dedup\' command retains multiple events for each
+ combination when you specify <int>. The number for <int>
+ must be greater than 0. If you do not specify a number, only the
+ first occurring event is kept. All other duplicates are removed from
+ the results. **Default:** 1
+- keepempty: optional. if true, keep the document if the any field in
+ the field-list has NULL value or field is MISSING. **Default:**
+ false.
+- consecutive: optional. If set to true, removes only events with
+ duplicate combinations of values that are consecutive. **Default:**
+ false.
+- field-list: mandatory. The comma-delimited field list. At least one
+ field is required.
+
+### Example 1: Dedup by one field
+
+The example show dedup the document with gender field.
+
+PPL query:
+
+ os> source=accounts | dedup gender | fields account_number, gender;
+ fetched rows / total rows = 2/2
+ +------------------+----------+
+ | account_number | gender |
+ |------------------+----------|
+ | 1 | M |
+ | 13 | F |
+ +------------------+----------+
+
+### Example 2: Keep 2 duplicates documents
+
+The example show dedup the document with gender field keep 2
+duplication.
+
+PPL query:
+
+ os> source=accounts | dedup 2 gender | fields account_number, gender;
+ fetched rows / total rows = 3/3
+ +------------------+----------+
+ | account_number | gender |
+ |------------------+----------|
+ | 1 | M |
+ | 6 | M |
+ | 13 | F |
+ +------------------+----------+
+
+### Example 3: Keep or Ignore the empty field by default
+
+The example show dedup the document by keep null value field.
+
+PPL query:
+
+ os> source=accounts | dedup email keepempty=true | fields account_number, email;
+ fetched rows / total rows = 4/4
+ +------------------+-----------------------+
+ | account_number | email |
+ |------------------+-----------------------|
+ | 1 | amberduke@pyrami.com |
+ | 6 | hattiebond@netagy.com |
+ | 13 | null |
+ | 18 | daleadams@boink.com |
+ +------------------+-----------------------+
+
+The example show dedup the document by ignore the empty value field.
+
+PPL query:
+
+ os> source=accounts | dedup email | fields account_number, email;
+ fetched rows / total rows = 3/3
+ +------------------+-----------------------+
+ | account_number | email |
+ |------------------+-----------------------|
+ | 1 | amberduke@pyrami.com |
+ | 6 | hattiebond@netagy.com |
+ | 18 | daleadams@boink.com |
+ +------------------+-----------------------+
+
+#### Example 4: Dedup in consecutive document
+
+The example show dedup the consecutive document.
+
+PPL query:
+
+ os> source=accounts | dedup gender consecutive=true | fields account_number, gender;
+ fetched rows / total rows = 3/3
+ +------------------+----------+
+ | account_number | gender |
+ |------------------+----------|
+ | 1 | M |
+ | 13 | F |
+ | 18 | M |
+ +------------------+----------+
+
+#### Limitation
+The \`dedup\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/eval.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/eval.ts
new file mode 100644
index 000000000..52a9429ed
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/eval.ts
@@ -0,0 +1,79 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const evalCmd = `## eval
+---
+
+### Description
+
+The \'eval\' command evaluate the expression and append the result to the
+search result.
+
+### Syntax
+
+eval <field>=<expression> \[","
+<field>=<expression> \]...
+
+- field: mandatory. If the field name not exist, a new field is added.
+ If the field name already exists, it will be overrided.
+- expression: mandatory. Any expression support by the system.
+
+### Example 1: Create the new field
+
+The example show to create new field doubleAge for each document. The
+new doubleAge is the evaluation result of age multiply by 2.
+
+PPL query:
+
+ os> source=accounts | eval doubleAge = age * 2 | fields age, doubleAge ;
+ fetched rows / total rows = 4/4
+ +-------+-------------+
+ | age | doubleAge |
+ |-------+-------------|
+ | 32 | 64 |
+ | 36 | 72 |
+ | 28 | 56 |
+ | 33 | 66 |
+ +-------+-------------+
+
+### Example 2: Override the existing field
+
+The example show to override the exist age field with age plus 1.
+
+PPL query:
+
+ os> source=accounts | eval age = age + 1 | fields age ;
+ fetched rows / total rows = 4/4
+ +-------+
+ | age |
+ |-------|
+ | 33 |
+ | 37 |
+ | 29 |
+ | 34 |
+ +-------+
+
+### Example 3: Create the new field with field defined in eval
+
+The example show to create a new field ddAge with field defined in eval
+command. The new field ddAge is the evaluation result of doubleAge
+multiply by 2, the doubleAge is defined in the eval command.
+
+PPL query:
+
+ os> source=accounts | eval doubleAge = age * 2, ddAge = doubleAge * 2 | fields age, doubleAge, ddAge ;
+ fetched rows / total rows = 4/4
+ +-------+-------------+---------+
+ | age | doubleAge | ddAge |
+ |-------+-------------+---------|
+ | 32 | 64 | 128 |
+ | 36 | 72 | 144 |
+ | 28 | 56 | 112 |
+ | 33 | 66 | 132 |
+ +-------+-------------+---------+
+
+#### Limitation
+The \`eval\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/fields.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/fields.ts
new file mode 100644
index 000000000..61a6954fd
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/fields.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const fieldsCmd = `## fields
+---
+### Description
+
+Using \`fields\` command to keep or remove fields from the search result.
+
+### Syntax
+
+fields \[+\|-\] <field-list>
+
+- index: optional. if the plus (+) is used, only the fields specified
+ in the field list will be keep. if the minus (-) is used, all the
+ fields specified in the field list will be removed. **Default** +
+- field list: mandatory. comma-delimited keep or remove fields.
+
+### Example 1: Select specified fields from result
+
+The example show fetch account\_number, firstname and lastname fields
+from search results.
+
+PPL query:
+
+ os> source=accounts | fields account_number, firstname, lastname;
+ fetched rows / total rows = 4/4
+ +------------------+-------------+------------+
+ | account_number | firstname | lastname |
+ |------------------+-------------+------------|
+ | 1 | Amber | Duke |
+ | 6 | Hattie | Bond |
+ | 13 | Nanette | Bates |
+ | 18 | Dale | Adams |
+ +------------------+-------------+------------+
+
+### Example 2: Remove specified fields from result
+
+The example show fetch remove account\_number field from search results.
+
+PPL query:
+
+ os> source=accounts | fields account_number, firstname, lastname | fields - account_number ;
+ fetched rows / total rows = 4/4
+ +-------------+------------+
+ | firstname | lastname |
+ |-------------+------------|
+ | Amber | Duke |
+ | Hattie | Bond |
+ | Nanette | Bates |
+ | Dale | Adams |
+ +-------------+------------+
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/head.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/head.ts
new file mode 100644
index 000000000..78ffe7b94
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/head.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const headCmd = `## head
+---
+
+### Description
+
+The \`head\` command returns the first N number of specified results in
+search order.
+
+### Syntax
+
+head \[N\]
+
+- N: optional. number of results to return. **Default:** 10
+
+### Example 1: Get first 10 results
+
+The example show first 10 results from accounts index.
+
+PPL query:
+
+ os> source=accounts | fields firstname, age | head;
+ fetched rows / total rows = 10/10
+ +---------------+-----------+
+ | firstname | age |
+ |---------------+-----------|
+ | Amber | 32 |
+ | Hattie | 36 |
+ | Nanette | 28 |
+ | Dale | 33 |
+ | Elinor | 36 |
+ | Virginia | 39 |
+ | Dillard | 34 |
+ | Mcgee | 39 |
+ | Aurelia | 37 |
+ | Fulton | 23 |
+ +---------------+-----------+
+
+### Example 2: Get first N results
+
+The example show first N results from accounts index.
+
+PPL query:
+
+ os> source=accounts | fields firstname, age | head 3;
+ fetched rows / total rows = 3/3
+ +---------------+-----------+
+ | firstname | age |
+ |---------------+-----------|
+ | Amber | 32 |
+ | Hattie | 36 |
+ | Nanette | 28 |
+ +---------------+-----------+
+
+#### Limitation
+The \`head\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/index.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/index.ts
new file mode 100644
index 000000000..27328a4c2
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { dedupCmd } from './dedup';
+export { evalCmd } from './eval';
+export { fieldsCmd } from './fields';
+export { headCmd } from './head';
+export { parseCmd } from './parse';
+export { rareCmd } from './rare';
+export { renameCmd } from './rename';
+export { searchCmd } from './search';
+export { sortCmd } from './sort';
+export { statsCmd } from './stats';
+export { syntaxCmd } from './syntax';
+export { topCmd } from './top';
+export { whereCmd } from './where';
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/parse.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/parse.ts
new file mode 100644
index 000000000..ee752c1ea
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/parse.ts
@@ -0,0 +1,110 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const parseCmd = `## parse
+---
+### Description
+
+The \`parse\` command parses a text field using a regular expression and append
+the result to the search result.
+
+### Syntax
+
+parse <field> <regular-expression>
+
+- field: mandatory. The field must be a text field.
+- regular-expression: mandatory. The regular expression used to extract new
+fields from given text field. If a new field name already exists, it will
+replace the original field.
+
+### Regular Expression
+
+The regular expression is used to match the whole text field of each document
+with Java regex engine. Each named capture group in the expression will become
+a new \`STRING\` field.
+
+### Example 1: Create the new field
+
+The example shows how to create new field \`host\` for each document. \`host\`
+will be the host name after \`@\` in \`email\` field. Parsing a null field will
+return an empty string.
+
+PPL query:
+
+ os> source=accounts | parse email '.+@(?.+)' | fields email, host ;
+ fetched rows / total rows = 4/4
+ +-----------------------+------------+
+ | email | host |
+ |-----------------------+------------|
+ | amberduke@pyrami.com | pyrami.com |
+ | hattiebond@netagy.com | netagy.com |
+ | null | |
+ | daleadams@boink.com | boink.com |
+ +-----------------------+------------+
+
+### Example 2: Override the existing field
+
+The example shows how to override the existing \`address\` field with street
+number removed.
+
+PPL query:
+
+ os> source=accounts | parse address '\\d+ (?.+)' | fields address ;
+ fetched rows / total rows = 4/4
+ +------------------+
+ | address |
+ |------------------|
+ | Holmes Lane |
+ | Bristol Street |
+ | Madison Street |
+ | Hutchinson Court |
+ +------------------+
+
+### Example 3: Filter and sort by casted parsed field
+
+The example shows how to sort street numbers that are higher than 500 in
+\`address\` field.
+
+PPL query:
+
+ os> source=accounts | parse address '(?\d+) (?.+)' | where cast(streetNumber as int) > 500 | sort num(streetNumber) | fields streetNumber, street ;
+ fetched rows / total rows = 3/3
+ +----------------+----------------+
+ | streetNumber | street |
+ |----------------+----------------|
+ | 671 | Bristol Street |
+ | 789 | Madison Street |
+ | 880 | Holmes Lane |
+ +----------------+----------------+
+
+### Limitation
+
+There are a few limitations with parse command:
+
+- Fields defined by parse cannot be parsed again.
+
+ The following command will not work:
+
+ source=accounts | parse address '\\d+ (?.+)' | parse street '\\w+ (?\\w+)' ;
+
+- Fields defined by parse cannot be overridden with other commands.
+
+ \`where\` will not match any documents since \`street\` cannot be overridden:
+
+ source=accounts | parse address '\\d+ (?.+)' | eval street='1' | where street='1' ;
+
+- The text field used by parse cannot be overridden.
+
+ \`street\` will not be successfully parsed since \`address\` is overridden:
+
+ source=accounts | parse address '\\d+ (?.+)' | eval address='1' ;
+
+- Fields defined by parse cannot be filtered/sorted after using them in
+\`stats\` command.
+
+ \`where\` in the following command will not work:
+
+ source=accounts | parse email '.+@(?.+)' | stats avg(age) by host | where host=pyrami.com ;
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rare.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rare.ts
new file mode 100644
index 000000000..37e504f33
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rare.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const rareCmd = `## rare
+---
+
+### Description
+
+Using \`rare\` command to find the least common tuple of values of all
+fields in the field list.
+
+**Note**: A maximum of 10 results is returned for each distinct tuple of
+values of the group-by fields.
+
+### Syntax
+
+rare <field-list> \[by-clause\]
+
+- field-list: mandatory. comma-delimited list of field names.
+- by-clause: optional. one or more fields to group the results by.
+
+### Example 1: Find the least common values in a field
+
+The example finds least common gender of all the accounts.
+
+PPL query:
+
+ os> source=accounts | rare gender;
+ fetched rows / total rows = 2/2
+ +------------+
+ | gender |
+ |------------|
+ | F |
+ |------------|
+ | M |
+ +------------+
+
+### Example 2: Find the least common values organized by gender
+
+The example finds least common age of all the accounts group by gender.
+
+PPL query:
+
+ os> source=accounts | rare age by gender;
+ fetched rows / total rows = 20/20
+ +----------+----------+
+ | gender | age |
+ |----------+----------|
+ | F | 29 |
+ | F | 20 |
+ | F | 23 |
+ | F | 25 |
+ | F | 37 |
+ | F | 38 |
+ | F | 40 |
+ | F | 27 |
+ | F | 36 |
+ | F | 24 |
+ | M | 27 |
+ | M | 24 |
+ | M | 34 |
+ | M | 38 |
+ | M | 28 |
+ | M | 39 |
+ | M | 21 |
+ | M | 30 |
+ | M | 25 |
+ | M | 29 |
+ +----------+----------+
+
+#### Limitation
+The \`rare\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rename.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rename.ts
new file mode 100644
index 000000000..46238384b
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/rename.ts
@@ -0,0 +1,57 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const renameCmd = `## rename
+---
+### Description
+
+Using \`rename\` command to rename one or more fields in the search
+result.
+
+### Syntax
+
+rename <source-field> AS <target-field>\[","
+<source-field> AS <target-field>\]...
+
+- source-field: mandatory. The name of the field you want to rename.
+- field list: mandatory. The name you want to rename to.
+
+### Example 1: Rename one field
+
+The example show rename one field.
+
+PPL query:
+
+ os> source=accounts | rename account_number as an | fields an;
+ fetched rows / total rows = 4/4
+ +------+
+ | an |
+ |------|
+ | 1 |
+ | 6 |
+ | 13 |
+ | 18 |
+ +------+
+
+### Example 2: Rename multiple fields
+
+The example show rename multiple fields.
+
+PPL query:
+
+ os> source=accounts | rename account_number as an, employer as emp | fields an, emp;
+ fetched rows / total rows = 4/4
+ +------+---------+
+ | an | emp |
+ |------+---------|
+ | 1 | Pyrami |
+ | 6 | Netagy |
+ | 13 | Quility |
+ | 18 | null |
+ +------+---------+
+
+#### Limitation
+The \`rename\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/search.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/search.ts
new file mode 100644
index 000000000..b54d5a739
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/search.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const searchCmd = `## search
+---
+
+### Description
+
+Using \`search\` command to retrieve document from the index. \`search\`
+command could be only used as the first command in the PPL query.
+
+### Syntax
+
+search source=<index> \[boolean-expression\]
+
+- search: search keywords, which could be ignore.
+- index: mandatory. search command must specify which index to query
+ from.
+- bool-expression: optional. any expression which could be evaluated
+ to boolean value.
+
+### Example 1: Fetch all the data
+
+The example show fetch all the document from accounts index.
+
+PPL query:
+
+ os> source=accounts;
+ fetched rows / total rows = 4/4
+ +----------------+-----------+----------------------+---------+--------+--------+----------+-------+-----+-----------------------+----------+
+ | account_number | firstname | address | balance | gender | city | employer | state | age | email | lastname |
+ +----------------+-----------+----------------------+---------+--------+--------+----------+-------+-----+-----------------------+----------+
+ | 1 | Amber | 880 Holmes Lane | 39225 | M | Brogan | Pyrami | IL | 32 | amberduke@pyrami.com | Duke |
+ | 6 | Hattie | 671 Bristol Street | 5686 | M | Dante | Netagy | TN | 36 | hattiebond@netagy.com | Bond |
+ | 13 | Nanette | 789 Madison Street | 32838 | F | Nogal | Quility | VA | 28 | null | Bates |
+ | 18 | Dale | 467 Hutchinson Court | 4180 | M | Orick | null | MD | 33 | daleadams@boink.com | Adams |
+ +----------------+-----------+----------------------+---------+--------+--------+----------+-------+-----+-----------------------+----------+
+
+### Example 2: Fetch data with condition
+
+The example show fetch all the document from accounts index with .
+
+PPL query:
+
+ os> source=accounts account_number=1 or gender="F";
+ fetched rows / total rows = 2/2
+ +------------------+-------------+--------------------+-----------+----------+--------+------------+---------+-------+----------------------+------------+
+ | account_number | firstname | address | balance | gender | city | employer | state | age | email | lastname |
+ |------------------+-------------+--------------------+-----------+----------+--------+------------+---------+-------+----------------------+------------|
+ | 1 | Amber | 880 Holmes Lane | 39225 | M | Brogan | Pyrami | IL | 32 | amberduke@pyrami.com | Duke |
+ | 13 | Nanette | 789 Madison Street | 32838 | F | Nogal | Quility | VA | 28 | null | Bates |
+ +------------------+-------------+--------------------+-----------+----------+--------+------------+---------+-------+----------------------+------------+
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/sort.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/sort.ts
new file mode 100644
index 000000000..e4c1f9404
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/sort.ts
@@ -0,0 +1,112 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const sortCmd = `## sort
+---
+### Description
+
+Using \`sort\` command to sorts all the search result by the specified
+fields.
+
+### Syntax
+
+sort <\[+\|-\] sort-field>...
+
+- \[+\|-\]: optional. The plus \[+\] stands for ascending order and
+ NULL/MISSING first and a minus \[-\] stands for descending order and
+ NULL/MISSING last. **Default:** ascending order and NULL/MISSING
+ first.
+- sort-field: mandatory. The field used to sort.
+
+### Example 1: Sort by one field
+
+The example show sort all the document with age field in ascending
+order.
+
+PPL query:
+
+ os> source=accounts | sort age | fields account_number, age;
+ fetched rows / total rows = 4/4
+ +------------------+-------+
+ | account_number | age |
+ |------------------+-------|
+ | 13 | 28 |
+ | 1 | 32 |
+ | 18 | 33 |
+ | 6 | 36 |
+ +------------------+-------+
+
+### Example 2: Sort by one field return all the result
+
+The example show sort all the document with age field in ascending
+order.
+
+PPL query:
+
+ os> source=accounts | sort age | fields account_number, age;
+ fetched rows / total rows = 4/4
+ +------------------+-------+
+ | account_number | age |
+ |------------------+-------|
+ | 13 | 28 |
+ | 1 | 32 |
+ | 18 | 33 |
+ | 6 | 36 |
+ +------------------+-------+
+
+### Example 3: Sort by one field in descending order
+
+The example show sort all the document with age field in descending
+order.
+
+PPL query:
+
+ os> source=accounts | sort - age | fields account_number, age;
+ fetched rows / total rows = 4/4
+ +------------------+-------+
+ | account_number | age |
+ |------------------+-------|
+ | 6 | 36 |
+ | 18 | 33 |
+ | 1 | 32 |
+ | 13 | 28 |
+ +------------------+-------+
+
+### Example 4: Sort by multiple field
+
+The example show sort all the document with gender field in ascending
+order and age field in descending.
+
+PPL query:
+
+ os> source=accounts | sort + gender, - age | fields account_number, gender, age;
+ fetched rows / total rows = 4/4
+ +------------------+----------+-------+
+ | account_number | gender | age |
+ |------------------+----------+-------|
+ | 13 | F | 28 |
+ | 6 | M | 36 |
+ | 18 | M | 33 |
+ | 1 | M | 32 |
+ +------------------+----------+-------+
+
+### Example 5: Sort by field include null value
+
+The example show sort employer field by default option (ascending order
+and null first), the result show that null value is in the first row.
+
+PPL query:
+
+ os> source=accounts | sort employer | fields employer;
+ fetched rows / total rows = 4/4
+ +------------+
+ | employer |
+ |------------|
+ | null |
+ | Netagy |
+ | Pyrami |
+ | Quility |
+ +------------+
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/stats.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/stats.ts
new file mode 100644
index 000000000..a3533193b
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/stats.ts
@@ -0,0 +1,353 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const statsCmd = `## stats
+---
+
+### Description
+
+Using \`stats\` command to calculate the aggregation from search result.
+
+The following table catalogs the aggregation functions and also
+indicates how the NULL/MISSING values is handled:
+
+| | | |
+|----------|-------------|-------------|
+| Function | NULL | MISSING |
+| COUNT | Not counted | Not counted |
+| SUM | Ignore | Ignore |
+| AVG | Ignore | Ignore |
+| MAX | Ignore | Ignore |
+| MIN | Ignore | Ignore |
+
+### Syntax
+
+stats <aggregation>... \[by-clause\]...
+
+- aggregation: mandatory. A aggregation function. The argument of
+ aggregation must be field.
+- by-clause: optional. The one or more fields to group the results by.
+ **Default**: If no <by-clause> is specified, the stats command
+ returns only one row, which is the aggregation over the entire
+ result set.
+
+### **Aggregation Functions**
+---
+### **COUNT**
+
+**Description**
+
+Usage: Returns a count of the number of expr in the rows retrieved by a
+SELECT statement.
+
+Example:
+
+ os> source=accounts | stats count();
+ fetched rows / total rows = 1/1
+ +-----------+
+ | count() |
+ |-----------|
+ | 4 |
+ +-----------+
+
+### **SUM**
+
+**Description**
+
+Usage: SUM(expr). Returns the sum of expr.
+
+Example:
+
+ os> source=accounts | stats sum(age) by gender;
+ fetched rows / total rows = 2/2
+ +------------+----------+
+ | sum(age) | gender |
+ |------------+----------|
+ | 28 | F |
+ | 101 | M |
+ +------------+----------+
+
+### **AVG**
+
+**Description**
+
+Usage: AVG(expr). Returns the average value of expr.
+
+Example:
+
+ os> source=accounts | stats avg(age) by gender;
+ fetched rows / total rows = 2/2
+ +--------------------+----------+
+ | avg(age) | gender |
+ |--------------------+----------|
+ | 28.0 | F |
+ | 33.666666666666664 | M |
+ +--------------------+----------+
+
+### **MAX**
+
+**Description**
+
+Usage: MAX(expr). Returns the maximum value of expr.
+
+Example:
+
+ os> source=accounts | stats max(age);
+ fetched rows / total rows = 1/1
+ +------------+
+ | max(age) |
+ |------------|
+ | 36 |
+ +------------+
+
+### **MIN**
+
+**Description**
+
+Usage: MIN(expr). Returns the minimum value of expr.
+
+Example:
+
+ os> source=accounts | stats min(age);
+ fetched rows / total rows = 1/1
+ +------------+
+ | min(age) |
+ |------------|
+ | 28 |
+ +------------+
+
+### **VAR\_SAMP**
+
+**Description**
+
+Usage: VAR\_SAMP(expr). Returns the sample variance of expr.
+
+Example:
+
+ os> source=accounts | stats var_samp(age);
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | var_samp(age) |
+ |--------------------|
+ | 10.916666666666666 |
+ +--------------------+
+
+### **VAR\_POP**
+
+**Description**
+
+Usage: VAR\_POP(expr). Returns the population standard variance of expr.
+
+Example:
+
+ os> source=accounts | stats var_pop(age);
+ fetched rows / total rows = 1/1
+ +----------------+
+ | var_pop(age) |
+ |----------------|
+ | 8.1875 |
+ +----------------+
+
+### **STDDEV\_SAMP**
+
+**Description**
+
+Usage: STDDEV\_SAMP(expr). Return the sample standard deviation of expr.
+
+Example:
+
+ os> source=accounts | stats stddev_samp(age);
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | stddev_samp(age) |
+ |--------------------|
+ | 3.304037933599835 |
+ +--------------------+
+
+### **STDDEV\_POP**
+
+**Description**
+
+Usage: STDDEV\_POP(expr). Return the population standard deviation of
+expr.
+
+Example:
+
+ os> source=accounts | stats stddev_pop(age);
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | stddev_pop(age) |
+ |--------------------|
+ | 2.8613807855648994 |
+ +--------------------+
+
+### **By Clause**
+
+The by clause could be the fields and expressions like scalar functions
+and aggregation functions. Besides, the span clause can also be used in
+the by clause to split specific field into buckets in the same interval,
+the stats then does the aggregation by these span buckets.
+
+The span syntax is \`span(field_expr, interval_expr)\`, the unit of the
+interval expression is the natural unit by default. If the field is a
+date and time type field, and the interval is in date/time units, you
+will need to specify the unit in the interval expression. For example,
+to split the field \`age\` into buckets by 10 years, it looks like
+\`span(age, 10)\`. And here is another example of time span, the span to
+split a \`timestamp\` field into hourly intervals, it looks like
+\`span(timestamp, 1h)\`.
+
+Available time unit:
+
+| Span Interval Units |
+|----------------------------|
+| millisecond (ms) |
+| second (s) |
+| minute (m, case sensitive) |
+| hour (h) |
+| day (d) |
+| week (w) |
+| month (M, case sensitive) |
+| quarter (q) |
+| year (y) |
+
+### Example 1: Calculate the count of events
+
+The example show calculate the count of events in the accounts.
+
+PPL query:
+
+ os> source=accounts | stats count();
+ fetched rows / total rows = 1/1
+ +-----------+
+ | count() |
+ |-----------|
+ | 4 |
+ +-----------+
+
+### Example 2: Calculate the average of a field
+
+The example show calculate the average age of all the accounts.
+
+PPL query:
+
+ os> source=accounts | stats avg(age);
+ fetched rows / total rows = 1/1
+ +------------+
+ | avg(age) |
+ |------------|
+ | 32.25 |
+ +------------+
+
+### Example 3: Calculate the average of a field by group
+
+The example show calculate the average age of all the accounts group by
+gender.
+
+PPL query:
+
+ os> source=accounts | stats avg(age) by gender;
+ fetched rows / total rows = 2/2
+ +--------------------+----------+
+ | avg(age) | gender |
+ |--------------------+----------|
+ | 28.0 | F |
+ | 33.666666666666664 | M |
+ +--------------------+----------+
+
+### Example 4: Calculate the average, sum and count of a field by group
+
+The example show calculate the average age, sum age and count of events
+of all the accounts group by gender.
+
+PPL query:
+
+ os> source=accounts | stats avg(age), sum(age), count() by gender;
+ fetched rows / total rows = 2/2
+ +--------------------+------------+-----------+----------+
+ | avg(age) | sum(age) | count() | gender |
+ |--------------------+------------+-----------+----------|
+ | 28.0 | 28 | 1 | F |
+ | 33.666666666666664 | 101 | 3 | M |
+ +--------------------+------------+-----------+----------+
+
+### Example 5: Calculate the maximum of a field
+
+The example calculates the max age of all the accounts.
+
+PPL query:
+
+ os> source=accounts | stats max(age);
+ fetched rows / total rows = 1/1
+ +------------+
+ | max(age) |
+ |------------|
+ | 36 |
+ +------------+
+
+### Example 6: Calculate the maximum and minimum of a field by group
+
+The example calculates the max and min age values of all the accounts
+group by gender.
+
+PPL query:
+
+ os> source=accounts | stats max(age), min(age) by gender;
+ fetched rows / total rows = 2/2
+ +------------+------------+----------+
+ | max(age) | min(age) | gender |
+ |------------+------------+----------|
+ | 28 | 28 | F |
+ | 36 | 32 | M |
+ +------------+------------+----------+
+
+### Example 7: Calculate the distinct count of a field
+
+To get the count of distinct values of a field, you can use
+\`DISTINCT_COUNT\` (or \`DC\`) function instead of \`COUNT\`. The example
+calculates both the count and the distinct count of gender field of all
+the accounts.
+
+PPL query:
+
+ os> source=accounts | stats count(gender), distinct_count(gender);
+ fetched rows / total rows = 1/1
+ +-----------------+--------------------------+
+ | count(gender) | distinct_count(gender) |
+ |-----------------+--------------------------|
+ | 4 | 2 |
+ +-----------------+--------------------------+
+
+### Example 8: Calculate the count by a span
+
+The example gets the count of age by the interval of 10 years.
+
+PPL query:
+
+ os> source=accounts | stats count(age) by span(age, 10) as age_span
+ fetched rows / total rows = 2/2
+ +--------------+------------+
+ | count(age) | age_span |
+ |--------------+------------|
+ | 1 | 20 |
+ | 3 | 30 |
+ +--------------+------------+
+
+### Example 9: Calculate the count by a gender and span
+
+The example gets the count of age by the interval of 10 years and group by gender.
+
+PPL query::
+
+ os> source=accounts | stats count() as cnt by span(age, 5) as age_span, gender
+ fetched rows / total rows = 3/3
+ +-------+------------+----------+
+ | cnt | age_span | gender |
+ |-------+------------+----------|
+ | 1 | 25 | F |
+ | 2 | 30 | M |
+ | 1 | 35 | M |
+ +-------+------------+----------+
+`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/syntax.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/syntax.ts
new file mode 100644
index 000000000..b579ac517
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/syntax.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const syntaxCmd = `## Syntax
+---
+### Command Order
+
+The PPL query started with \`search\` command to reference a table search
+from. All the following command could be in any order. In the following
+example, \`search\` command refer the accounts index as the source, then
+using fields and where command to do the further processing.
+
+\`\`\`
+search source=accounts
+| where age > 18
+| fields firstname, lastname
+\`\`\`
+
+### Required arguments
+
+Required arguments are shown in angle brackets \< \>.
+
+### Optional arguments
+
+Optional arguments are enclosed in square brackets \[ \].`;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/top.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/top.ts
new file mode 100644
index 000000000..aa7db2958
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/top.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const topCmd = `## top
+---
+### Description
+
+Using \`top\` command to find the most common tuple of values of all
+fields in the field list.
+
+### Syntax
+
+top \[N\] <field-list> \[by-clause\]
+
+- N: number of results to return. **Default**: 10
+- field-list: mandatory. comma-delimited list of field names.
+- by-clause: optional. one or more fields to group the results by.
+
+### Example 1: Find the most common values in a field
+
+The example finds most common gender of all the accounts.
+
+PPL query:
+
+ os> source=accounts | top gender;
+ fetched rows / total rows = 2/2
+ +------------+
+ | gender |
+ |------------|
+ | M |
+ |------------|
+ | F |
+ +------------+
+
+### Example 2: Find the most common values in a field
+
+The example finds most common gender of all the accounts.
+
+PPL query:
+
+ os> source=accounts | top 1 gender;
+ fetched rows / total rows = 1/1
+ +------------+
+ | gender |
+ |------------|
+ | M |
+ +------------+
+
+### Example 3: Find the most common values organized by gender
+
+The example finds most common age of all the accounts group by gender.
+
+PPL query:
+
+ os> source=accounts | top 1 age by gender;
+ fetched rows / total rows = 2/2
+ +----------+----------+
+ | gender | age |
+ |----------+----------|
+ | F | 39 |
+ | M | 31 |
+ +----------+----------+
+
+#### Limitation
+The \`top\` command is not rewritten to OpenSearch DSL, it is only executed on the coordination node.
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/commands/where.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/where.ts
new file mode 100644
index 000000000..9adbcb739
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/commands/where.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const whereCmd = `## where
+---
+
+### Description
+
+The \`where\` command bool-expression to filter the search result. The
+\`where\` command only return the result when bool-expression evaluated to
+true.
+
+### Syntax
+
+where <boolean-expression>
+
+- bool-expression: optional. any expression which could be evaluated
+ to boolean value.
+
+### Example 1: Filter result set with condition
+
+The example show fetch all the document from accounts index with .
+
+PPL query:
+
+ os> source=accounts | where account_number=1 or gender="F" | fields account_number, gender;
+ fetched rows / total rows = 2/2
+ +------------------+----------+
+ | account_number | gender |
+ |------------------+----------|
+ | 1 | M |
+ | 13 | F |
+ +------------------+----------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/condition.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/condition.ts
new file mode 100644
index 000000000..85e3ed074
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/condition.ts
@@ -0,0 +1,176 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const conditionFunction = `## Condition
+---
+
+### Description
+
+Usage: isnull(field) return true if field is null.
+
+Argument type: all the supported data type.
+
+Return type: BOOLEAN
+
+Example:
+
+ os> source=accounts | eval result = isnull(employer) | fields result, employer, firstname
+ fetched rows / total rows = 4/4
+ +----------+------------+-------------+
+ | result | employer | firstname |
+ |----------+------------+-------------|
+ | False | Pyrami | Amber |
+ | False | Netagy | Hattie |
+ | False | Quility | Nanette |
+ | True | null | Dale |
+ +----------+------------+-------------+
+
+### **ISNOTNULL**
+
+**Description**
+
+Usage: isnotnull(field) return true if field is not null.
+
+Argument type: all the supported data type.
+
+Return type: BOOLEAN
+
+Example:
+
+ os> source=accounts | where not isnotnull(employer) | fields account_number, employer
+ fetched rows / total rows = 1/1
+ +------------------+------------+
+ | account_number | employer |
+ |------------------+------------|
+ | 18 | null |
+ +------------------+------------+
+
+### **EXISTS**
+
+[Because OpenSearch doesn't differentiate null and
+missing](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html).
+so we can't provide function like ismissing/isnotmissing to test field
+exist or not. But you can still use isnull/isnotnull for such purpose.
+
+Example, the account 13 doesn't have email field:
+
+ os> source=accounts | where isnull(email) | fields account_number, email
+ fetched rows / total rows = 1/1
+ +------------------+---------+
+ | account_number | email |
+ |------------------+---------|
+ | 13 | null |
+ +------------------+---------+
+
+### **IFNULL**
+
+**Description**
+
+Usage: ifnull(field1, field2) return field2 if field1 is null.
+
+Argument type: all the supported data type, (NOTE : if two parameters
+has different type, you will fail semantic check.)
+
+Return type: any
+
+Example:
+
+ os> source=accounts | eval result = ifnull(employer, 'default') | fields result, employer, firstname
+ fetched rows / total rows = 4/4
+ +----------+------------+-------------+
+ | result | employer | firstname |
+ |----------+------------+-------------|
+ | Pyrami | Pyrami | Amber |
+ | Netagy | Netagy | Hattie |
+ | Quility | Quility | Nanette |
+ | default | null | Dale |
+ +----------+------------+-------------+
+
+### **NULLIF**
+
+**Description**
+
+Usage: nullif(field1, field2) return null if two parameters are same,
+otherwiser return field1.
+
+Argument type: all the supported data type, (NOTE : if two parameters
+has different type, if two parameters has different type, you will fail
+semantic check)
+
+Return type: any
+
+Example:
+
+ os> source=accounts | eval result = nullif(employer, 'Pyrami') | fields result, employer, firstname
+ fetched rows / total rows = 4/4
+ +----------+------------+-------------+
+ | result | employer | firstname |
+ |----------+------------+-------------|
+ | null | Pyrami | Amber |
+ | Netagy | Netagy | Hattie |
+ | Quility | Quility | Nanette |
+ | null | null | Dale |
+ +----------+------------+-------------+
+
+### **ISNULL**
+
+**Description**
+
+Usage: isnull(field1, field2) return null if two parameters are same,
+otherwise return field1.
+
+Argument type: all the supported data type
+
+Return type: any
+
+Example:
+
+ os> source=accounts | eval result = isnull(employer) | fields result, employer, firstname
+ fetched rows / total rows = 4/4
+ +----------+------------+-------------+
+ | result | employer | firstname |
+ |----------+------------+-------------|
+ | False | Pyrami | Amber |
+ | False | Netagy | Hattie |
+ | False | Quility | Nanette |
+ | True | null | Dale |
+ +----------+------------+-------------+
+
+### **IF**
+
+**Description**
+
+Usage: if(condition, expr1, expr2) return expr1 if condition is true,
+otherwiser return expr2.
+
+Argument type: all the supported data type, (NOTE : if expr1 and expr2
+are different type, you will fail semantic check
+
+Return type: any
+
+Example:
+
+ os> source=accounts | eval result = if(true, firstname, lastname) | fields result, firstname, lastname
+ fetched rows / total rows = 4/4
+ +----------+-------------+------------+
+ | result | firstname | lastname |
+ |----------+-------------+------------|
+ | Amber | Amber | Duke |
+ | Hattie | Hattie | Bond |
+ | Nanette | Nanette | Bates |
+ | Dale | Dale | Adams |
+ +----------+-------------+------------+
+
+ os> source=accounts | eval result = if(false, firstname, lastname) | fields result, firstname, lastname
+ fetched rows / total rows = 4/4
+ +----------+-------------+------------+
+ | result | firstname | lastname |
+ |----------+-------------+------------|
+ | Duke | Amber | Duke |
+ | Bond | Hattie | Bond |
+ | Bates | Nanette | Bates |
+ | Adams | Dale | Adams |
+ +----------+-------------+------------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/datetime.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/datetime.ts
new file mode 100644
index 000000000..a593b1c56
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/datetime.ts
@@ -0,0 +1,640 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const datetimeFunction = `## Datetime
+---
+
+### **ADDDATE**
+
+Description
+
+Usage: adddate(date, INTERVAL expr unit)/ adddate(date, expr) adds the
+time interval of second argument to date; adddate(date, days) adds the
+second argument as integer number of days to date.
+
+Argument type: DATE/DATETIME/TIMESTAMP/STRING, INTERVAL/LONG
+
+Return type map:
+
+(DATE/DATETIME/TIMESTAMP/STRING, INTERVAL) -> DATETIME
+
+(DATE, LONG) -> DATE
+
+(DATETIME/TIMESTAMP/STRING, LONG) -> DATETIME
+
+Synonyms: [DATE\_ADD](#date_add)
+
+Example:
+
+ os> source=people | eval \`ADDDATE(DATE('2020-08-26'), INTERVAL 1 HOUR)\` = ADDDATE(DATE('2020-08-26'), INTERVAL 1 HOUR), \`ADDDATE(DATE('2020-08-26'), 1)\` = ADDDATE(DATE('2020-08-26'), 1), \`ADDDATE(TIMESTAMP('2020-08-26 01:01:01'), 1)\` = ADDDATE(TIMESTAMP('2020-08-26 01:01:01'), 1) | fields \`ADDDATE(DATE('2020-08-26'), INTERVAL 1 HOUR)\`, \`ADDDATE(DATE('2020-08-26'), 1)\`, \`ADDDATE(TIMESTAMP('2020-08-26 01:01:01'), 1)\`
+ fetched rows / total rows = 1/1
+ +------------------------------------------------+----------------------------------+------------------------------------------------+
+ | ADDDATE(DATE('2020-08-26'), INTERVAL 1 HOUR) | ADDDATE(DATE('2020-08-26'), 1) | ADDDATE(TIMESTAMP('2020-08-26 01:01:01'), 1) |
+ |------------------------------------------------+----------------------------------+------------------------------------------------|
+ | 2020-08-26 01:00:00 | 2020-08-27 | 2020-08-27 01:01:01 |
+ +------------------------------------------------+----------------------------------+------------------------------------------------+
+
+### **DATE**
+
+**Description**
+
+Usage: date(expr) constructs a date type with the input string expr as a
+date. If the argument is of date/datetime/timestamp, it extracts the
+date value part from the expression.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: DATE
+
+Example:
+
+ >od source=people | eval \`DATE('2020-08-26')\` = DATE('2020-08-26'), \`DATE(TIMESTAMP('2020-08-26 13:49:00'))\` = DATE(TIMESTAMP('2020-08-26 13:49:00')) | fields \`DATE('2020-08-26')\`, \`DATE(TIMESTAMP('2020-08-26 13:49:00'))\`
+ fetched rows / total rows = 1/1
+ +----------------------+------------------------------------------+
+ | DATE('2020-08-26') | DATE(TIMESTAMP('2020-08-26 13:49:00')) |
+ |----------------------+------------------------------------------|
+ | DATE '2020-08-26' | DATE '2020-08-26' |
+ +----------------------+------------------------------------------+
+
+### **DATE\_ADD**
+
+**Description**
+
+Usage: date\_add(date, INTERVAL expr unit)/ date\_add(date, expr) adds
+the time interval expr to date
+
+Argument type: DATE/DATETIME/TIMESTAMP/STRING, INTERVAL/LONG
+
+Return type map:
+
+DATE/DATETIME/TIMESTAMP/STRING, INTERVAL -> DATETIME
+
+DATE, LONG -> DATE
+
+DATETIME/TIMESTAMP/STRING, LONG -> DATETIME
+
+Synonyms: [ADDDATE](#adddate)
+
+Example:
+
+ os> source=people | eval \`DATE_ADD(DATE('2020-08-26'), INTERVAL 1 HOUR)\` = DATE_ADD(DATE('2020-08-26'), INTERVAL 1 HOUR), \`DATE_ADD(DATE('2020-08-26'), 1)\` = DATE_ADD(DATE('2020-08-26'), 1), \`DATE_ADD(TIMESTAMP('2020-08-26 01:01:01'), 1)\` = DATE_ADD(TIMESTAMP('2020-08-26 01:01:01'), 1) | fields \`DATE_ADD(DATE('2020-08-26'), INTERVAL 1 HOUR)\`, \`DATE_ADD(DATE('2020-08-26'), 1)\`, \`DATE_ADD(TIMESTAMP('2020-08-26 01:01:01'), 1)\`
+ fetched rows / total rows = 1/1
+ +-------------------------------------------------+-----------------------------------+-------------------------------------------------+
+ | DATE_ADD(DATE('2020-08-26'), INTERVAL 1 HOUR) | DATE_ADD(DATE('2020-08-26'), 1) | DATE_ADD(TIMESTAMP('2020-08-26 01:01:01'), 1) |
+ |-------------------------------------------------+-----------------------------------+-------------------------------------------------|
+ | 2020-08-26 01:00:00 | 2020-08-27 | 2020-08-27 01:01:01 |
+ +-------------------------------------------------+-----------------------------------+-------------------------------------------------+
+
+### **DATE\_FORMAT**
+
+**Description**
+
+Usage: date\_format(date, format) formats the date argument using the
+specifiers in the format argument.
+
+| Specifier | Description |
+|-----------|--------------------------------------------------------------------------------------------------|
+| %a | Abbreviated weekday name (Sun..Sat) |
+| %b | Abbreviated month name (Jan..Dec) |
+| %c | Month, numeric (0..12) |
+| %D | Day of the month with English suffix (0th, 1st, 2nd, 3rd, …) |
+| %d | Day of the month, numeric (00..31) |
+| %e | Day of the month, numeric (0..31) |
+| %f | Microseconds (000000..999999) |
+| %H | Hour (00..23) |
+| %h | Hour (01..12) |
+| %I | Hour (01..12) |
+| %i | Minutes, numeric (00..59) |
+| %j | Day of year (001..366) |
+| %k | Hour (0..23) |
+| %l | Hour (1..12) |
+| %M | Month name (January..December) |
+| %m | Month, numeric (00..12) |
+| %p | AM or PM |
+| %r | Time, 12-hour (hh:mm:ss followed by AM or PM) |
+| %S | Seconds (00..59) |
+| %s | Seconds (00..59) |
+| %T | Time, 24-hour (hh:mm:ss) |
+| %U | Week (00..53), where Sunday is the first day of the week; WEEK() mode 0 |
+| %u | Week (00..53), where Monday is the first day of the week; WEEK() mode 1 |
+| %V | Week (01..53), where Sunday is the first day of the week; WEEK() mode 2; used with %X |
+| %v | Week (01..53), where Monday is the first day of the week; WEEK() mode 3; used with %x |
+| %W | Weekday name (Sunday..Saturday) |
+| %w | Day of the week (0=Sunday..6=Saturday) |
+| %X | Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V |
+| %x | Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v |
+| %Y | Year, numeric, four digits |
+| %y | Year, numeric (two digits) |
+| %% | A literal % character |
+| %x | x, for any “x” not listed above |
+
+The following table describes the available specifier arguments.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP, STRING
+
+Return type: STRING
+
+Example:
+
+ >od source=people | eval \`DATE_FORMAT('1998-01-31 13:14:15.012345', '%T.%f')\` = DATE_FORMAT('1998-01-31 13:14:15.012345', '%T.%f'), \`DATE_FORMAT(TIMESTAMP('1998-01-31 13:14:15.012345'), '%Y-%b-%D %r')\` = DATE_FORMAT(TIMESTAMP('1998-01-31 13:14:15.012345'), '%Y-%b-%D %r') | fields \`DATE_FORMAT('1998-01-31 13:14:15.012345', '%T.%f')\`, \`DATE_FORMAT(TIMESTAMP('1998-01-31 13:14:15.012345'), '%Y-%b-%D %r')\`
+ fetched rows / total rows = 1/1
+ +-----------------------------------------------+----------------------------------------------------------------+
+ | DATE('1998-01-31 13:14:15.012345', '%T.%f') | DATE(TIMESTAMP('1998-01-31 13:14:15.012345'), '%Y-%b-%D %r') |
+ |-----------------------------------------------+----------------------------------------------------------------|
+ | '13:14:15.012345' | '1998-Jan-31st 01:14:15 PM' |
+ +-----------------------------------------------+----------------------------------------------------------------+
+
+### **DATE\_SUB**
+
+**Description**
+
+Usage: date\_sub(date, INTERVAL expr unit)/ date\_sub(date, expr)
+subtracts the time interval expr from date
+
+Argument type: DATE/DATETIME/TIMESTAMP/STRING, INTERVAL/LONG
+
+Return type map:
+
+DATE/DATETIME/TIMESTAMP/STRING, INTERVAL -> DATETIME
+
+DATE, LONG -> DATE
+
+DATETIME/TIMESTAMP/STRING, LONG -> DATETIME
+
+Synonyms: [SUBDATE](#subdate)
+
+Example:
+
+ os> source=people | eval \`DATE_SUB(DATE('2008-01-02'), INTERVAL 31 DAY)\` = DATE_SUB(DATE('2008-01-02'), INTERVAL 31 DAY), \`DATE_SUB(DATE('2020-08-26'), 1)\` = DATE_SUB(DATE('2020-08-26'), 1), \`DATE_SUB(TIMESTAMP('2020-08-26 01:01:01'), 1)\` = DATE_SUB(TIMESTAMP('2020-08-26 01:01:01'), 1) | fields \`DATE_SUB(DATE('2008-01-02'), INTERVAL 31 DAY)\`, \`DATE_SUB(DATE('2020-08-26'), 1)\`, \`DATE_SUB(TIMESTAMP('2020-08-26 01:01:01'), 1)\`
+ fetched rows / total rows = 1/1
+ +-------------------------------------------------+-----------------------------------+-------------------------------------------------+
+ | DATE_SUB(DATE('2008-01-02'), INTERVAL 31 DAY) | DATE_SUB(DATE('2020-08-26'), 1) | DATE_SUB(TIMESTAMP('2020-08-26 01:01:01'), 1) |
+ |-------------------------------------------------+-----------------------------------+-------------------------------------------------|
+ | 2007-12-02 | 2020-08-25 | 2020-08-25 01:01:01 |
+ +-------------------------------------------------+-----------------------------------+-------------------------------------------------+
+
+### **DAY**
+
+**Description**
+
+Usage: day(date) extracts the day of the month for date, in the range 1
+to 31. The dates with value 0 such as '0000-00-00' or '2008-00-00' are
+invalid.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Synonyms: DAYOFMONTH
+
+Example:
+
+ os> source=people | eval \`DAY(DATE('2020-08-26'))\` = DAY(DATE('2020-08-26')) | fields \`DAY(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +---------------------------+
+ | DAY(DATE('2020-08-26')) |
+ |---------------------------|
+ | 26 |
+ +---------------------------+
+
+### **DAYNAME**
+
+**Description**
+
+Usage: dayname(date) returns the name of the weekday for date, including
+Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`DAYNAME(DATE('2020-08-26'))\` = DAYNAME(DATE('2020-08-26')) | fields \`DAYNAME(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +-------------------------------+
+ | DAYNAME(DATE('2020-08-26')) |
+ |-------------------------------|
+ | Wednesday |
+ +-------------------------------+
+
+### **DAYOFMONTH**
+
+**Description**
+
+Usage: dayofmonth(date) extracts the day of the month for date, in the
+range 1 to 31. The dates with value 0 such as '0000-00-00' or
+'2008-00-00' are invalid.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Synonyms: DAY
+
+Example:
+
+ os> source=people | eval \`DAYOFMONTH(DATE('2020-08-26'))\` = DAYOFMONTH(DATE('2020-08-26')) | fields \`DAYOFMONTH(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +----------------------------------+
+ | DAYOFMONTH(DATE('2020-08-26')) |
+ |----------------------------------|
+ | 26 |
+ +----------------------------------+
+
+### **DAYOFWEEK**
+
+**Description**
+
+Usage: dayofweek(date) returns the weekday index for date (1 = Sunday, 2
+= Monday, …, 7 = Saturday).
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`DAYOFWEEK(DATE('2020-08-26'))\` = DAYOFWEEK(DATE('2020-08-26')) | fields \`DAYOFWEEK(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +---------------------------------+
+ | DAYOFWEEK(DATE('2020-08-26')) |
+ |---------------------------------|
+ | 4 |
+ +---------------------------------+
+
+### **DAYOFYEAR**
+
+**Description**
+
+Usage: dayofyear(date) returns the day of the year for date, in the
+range 1 to 366.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`DAYOFYEAR(DATE('2020-08-26'))\` = DAYOFYEAR(DATE('2020-08-26')) | fields \`DAYOFYEAR(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +---------------------------------+
+ | DAYOFYEAR(DATE('2020-08-26')) |
+ |---------------------------------|
+ | 239 |
+ +---------------------------------+
+
+### **FROM\_DAYS**
+
+**Description**
+
+Usage: from\_days(N) returns the date value given the day number N.
+
+Argument type: INTEGER/LONG
+
+Return type: DATE
+
+Example:
+
+ os> source=people | eval \`FROM_DAYS(733687)\` = FROM_DAYS(733687) | fields \`FROM_DAYS(733687)\`
+ fetched rows / total rows = 1/1
+ +---------------------+
+ | FROM_DAYS(733687) |
+ |---------------------|
+ | 2008-10-07 |
+ +---------------------+
+
+### **HOUR**
+
+**Description**
+
+Usage: hour(time) extracts the hour value for time. Different from the
+time of day value, the time value has a large range and can be greater
+than 23, so the return value of hour(time) can be also greater than 23.
+
+Argument type: STRING/TIME/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`HOUR(TIME('01:02:03'))\` = HOUR(TIME('01:02:03')) | fields \`HOUR(TIME('01:02:03'))\`
+ fetched rows / total rows = 1/1
+ +--------------------------+
+ | HOUR(TIME('01:02:03')) |
+ |--------------------------|
+ | 1 |
+ +--------------------------+
+
+### **MAKETIME**
+
+**Description**
+
+Specifications:
+
+1. MAKETIME(INTEGER, INTEGER, INTEGER) -> DATE
+
+### **MICROSECOND**
+
+**Description**
+
+Usage: microsecond(expr) returns the microseconds from the time or
+datetime expression expr as a number in the range from 0 to 999999.
+
+Argument type: STRING/TIME/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`MICROSECOND(TIME('01:02:03.123456'))\` = MICROSECOND(TIME('01:02:03.123456')) | fields \`MICROSECOND(TIME('01:02:03.123456'))\`
+ fetched rows / total rows = 1/1
+ +----------------------------------------+
+ | MICROSECOND(TIME('01:02:03.123456')) |
+ |----------------------------------------|
+ | 123456 |
+ +----------------------------------------+
+
+### **MINUTE**
+
+**Description**
+
+Usage: minute(time) returns the minute for time, in the range 0 to 59.
+
+Argument type: STRING/TIME/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`MINUTE(TIME('01:02:03'))\` = MINUTE(TIME('01:02:03')) | fields \`MINUTE(TIME('01:02:03'))\`
+ fetched rows / total rows = 1/1
+ +----------------------------+
+ | MINUTE(TIME('01:02:03')) |
+ |----------------------------|
+ | 2 |
+ +----------------------------+
+
+### **MONTH**
+
+**Description**
+
+Usage: month(date) returns the month for date, in the range 1 to 12 for
+January to December. The dates with value 0 such as '0000-00-00' or
+'2008-00-00' are invalid.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`MONTH(DATE('2020-08-26'))\` = MONTH(DATE('2020-08-26')) | fields \`MONTH(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +-----------------------------+
+ | MONTH(DATE('2020-08-26')) |
+ |-----------------------------|
+ | 8 |
+ +-----------------------------+
+
+### **MONTHNAME**
+
+**Description**
+
+Usage: monthname(date) returns the full name of the month for date.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`MONTHNAME(DATE('2020-08-26'))\` = MONTHNAME(DATE('2020-08-26')) | fields \`MONTHNAME(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +---------------------------------+
+ | MONTHNAME(DATE('2020-08-26')) |
+ |---------------------------------|
+ | August |
+ +---------------------------------+
+
+### **NOW**
+
+**Description**
+
+Specifications:
+
+1. NOW() -> DATE
+
+### **QUARTER**
+
+**Description**
+
+Usage: quarter(date) returns the quarter of the year for date, in the
+range 1 to 4.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`QUARTER(DATE('2020-08-26'))\` = QUARTER(DATE('2020-08-26')) | fields \`QUARTER(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +-------------------------------+
+ | QUARTER(DATE('2020-08-26')) |
+ |-------------------------------|
+ | 3 |
+ +-------------------------------+
+
+### **SECOND**
+
+**Description**
+
+Usage: second(time) returns the second for time, in the range 0 to 59.
+
+Argument type: STRING/TIME/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`SECOND(TIME('01:02:03'))\` = SECOND(TIME('01:02:03')) | fields \`SECOND(TIME('01:02:03'))\`
+ fetched rows / total rows = 1/1
+ +----------------------------+
+ | SECOND(TIME('01:02:03')) |
+ |----------------------------|
+ | 3 |
+ +----------------------------+
+
+### **SUBDATE**
+
+**Description**
+
+Usage: subdate(date, INTERVAL expr unit)/ subdate(date, expr) subtracts
+the time interval expr from date
+
+Argument type: DATE/DATETIME/TIMESTAMP/STRING, INTERVAL/LONG
+
+Return type map:
+
+DATE/DATETIME/TIMESTAMP/STRING, INTERVAL -> DATETIME
+
+DATE, LONG -> DATE
+
+DATETIME/TIMESTAMP/STRING, LONG -> DATETIME
+
+Synonyms: [DATE\_SUB](#date_sub)
+
+Example:
+
+ os> source=people | eval \`SUBDATE(DATE('2008-01-02'), INTERVAL 31 DAY)\` = SUBDATE(DATE('2008-01-02'), INTERVAL 31 DAY), \`SUBDATE(DATE('2020-08-26'), 1)\` = SUBDATE(DATE('2020-08-26'), 1), \`SUBDATE(TIMESTAMP('2020-08-26 01:01:01'), 1)\` = SUBDATE(TIMESTAMP('2020-08-26 01:01:01'), 1) | fields \`SUBDATE(DATE('2008-01-02'), INTERVAL 31 DAY)\`, \`SUBDATE(DATE('2020-08-26'), 1)\`, \`SUBDATE(TIMESTAMP('2020-08-26 01:01:01'), 1)\`
+ fetched rows / total rows = 1/1
+ +------------------------------------------------+----------------------------------+------------------------------------------------+
+ | SUBDATE(DATE('2008-01-02'), INTERVAL 31 DAY) | SUBDATE(DATE('2020-08-26'), 1) | SUBDATE(TIMESTAMP('2020-08-26 01:01:01'), 1) |
+ |------------------------------------------------+----------------------------------+------------------------------------------------|
+ | 2007-12-02 | 2020-08-25 | 2020-08-25 01:01:01 |
+ +------------------------------------------------+----------------------------------+------------------------------------------------+
+
+### **TIME**
+
+**Description**
+
+Usage: time(expr) constructs a time type with the input string expr as a
+time. If the argument is of date/datetime/time/timestamp, it extracts
+the time value part from the expression.
+
+Argument type: STRING/DATE/DATETIME/TIME/TIMESTAMP
+
+Return type: TIME
+
+Example:
+
+ >od source=people | eval \`TIME('13:49:00')\` = TIME('13:49:00'), \`TIME(TIMESTAMP('2020-08-26 13:49:00'))\` = TIME(TIMESTAMP('2020-08-26 13:49:00')) | fields \`TIME('13:49:00')\`, \`TIME(TIMESTAMP('2020-08-26 13:49:00'))\`
+ fetched rows / total rows = 1/1
+ +--------------------+------------------------------------------+
+ | TIME('13:49:00') | TIME(TIMESTAMP('2020-08-26 13:49:00')) |
+ |--------------------+------------------------------------------|
+ | TIME '13:49:00' | TIME '13:49:00' |
+ +--------------------+------------------------------------------+
+
+### **TIME\_TO\_SEC**
+
+**Description**
+
+Usage: time\_to\_sec(time) returns the time argument, converted to
+seconds.
+
+Argument type: STRING/TIME/DATETIME/TIMESTAMP
+
+Return type: LONG
+
+Example:
+
+ os> source=people | eval \`TIME_TO_SEC(TIME('22:23:00'))\` = TIME_TO_SEC(TIME('22:23:00')) | fields \`TIME_TO_SEC(TIME('22:23:00'))\`
+ fetched rows / total rows = 1/1
+ +---------------------------------+
+ | TIME_TO_SEC(TIME('22:23:00')) |
+ |---------------------------------|
+ | 80580 |
+ +---------------------------------+
+
+### **TIMESTAMP**
+
+**Description**
+
+Usage: timestamp(expr) construct a timestamp type with the input string
+expr as an timestamp. If the argument is of date/datetime/timestamp
+type, cast expr to timestamp type with default timezone UTC.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: TIMESTAMP
+
+Example:
+
+ >od source=people | eval \`TIMESTAMP('2020-08-26 13:49:00')\` = TIMESTAMP('2020-08-26 13:49:00') | fields \`TIMESTAMP('2020-08-26 13:49:00')\`
+ fetched rows / total rows = 1/1
+ +------------------------------------+
+ | TIMESTAMP('2020-08-26 13:49:00') |
+ |------------------------------------|
+ | TIMESTAMP '2020-08-26 13:49:00 |
+ +------------------------------------+
+
+### **TO\_DAYS**
+
+**Description**
+
+Usage: to\_days(date) returns the day number (the number of days since
+year 0) of the given date. Returns NULL if date is invalid.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: LONG
+
+Example:
+
+ os> source=people | eval \`TO_DAYS(DATE('2008-10-07'))\` = TO_DAYS(DATE('2008-10-07')) | fields \`TO_DAYS(DATE('2008-10-07'))\`
+ fetched rows / total rows = 1/1
+ +-------------------------------+
+ | TO_DAYS(DATE('2008-10-07')) |
+ |-------------------------------|
+ | 733687 |
+ +-------------------------------+
+
+### **WEEK**
+
+**Description**
+
+Usage: week(date\[, mode\]) returns the week number for date. If the
+mode argument is omitted, the default mode 0 is used.
+
+| Mode | First day of week | Range | Week 1 is the first week … |
+|------|-------------------|-------|-------------------------------|
+| 0 | Sunday | 0-53 | with a Sunday in this year |
+| 1 | Monday | 0-53 | with 4 or more days this year |
+| 2 | Sunday | 1-53 | with a Sunday in this year |
+| 3 | Monday | 1-53 | with 4 or more days this year |
+| 4 | Sunday | 0-53 | with 4 or more days this year |
+| 5 | Monday | 0-53 | with a Monday in this year |
+| 6 | Sunday | 1-53 | with 4 or more days this year |
+| 7 | Monday | 1-53 | with a Monday in this year |
+
+The following table describes how the mode argument works.
+
+Argument type: DATE/DATETIME/TIMESTAMP/STRING
+
+Return type: INTEGER
+
+Example:
+
+ >od source=people | eval \`WEEK(DATE('2008-02-20'))\` = WEEK(DATE('2008-02-20')), \`WEEK(DATE('2008-02-20'), 1)\` = WEEK(DATE('2008-02-20'), 1) | fields \`WEEK(DATE('2008-02-20'))\`, \`WEEK(DATE('2008-02-20'), 1)\`
+ fetched rows / total rows = 1/1
+ +----------------------------+-------------------------------+
+ | WEEK(DATE('2008-02-20')) | WEEK(DATE('2008-02-20'), 1) |
+ |----------------------------|-------------------------------|
+ | 7 | 8 |
+ +----------------------------+-------------------------------+
+
+### **YEAR**
+
+**Description**
+
+Usage: year(date) returns the year for date, in the range 1000 to 9999,
+or 0 for the “zero” date.
+
+Argument type: STRING/DATE/DATETIME/TIMESTAMP
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`YEAR(DATE('2020-08-26'))\` = YEAR(DATE('2020-08-26')) | fields \`YEAR(DATE('2020-08-26'))\`
+ fetched rows / total rows = 1/1
+ +----------------------------+
+ | YEAR(DATE('2020-08-26')) |
+ |----------------------------|
+ | 2020 |
+ +----------------------------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/full_text_search.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/full_text_search.ts
new file mode 100644
index 000000000..4704df6ad
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/full_text_search.ts
@@ -0,0 +1,82 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const fullTextSearchFunction = `## Full Text Search
+---
+
+The full text search based functions enable users to search the index for
+documents by the full text search of the input query. The functions are built
+on the top of the search queries of the OpenSearch engine, but in memory
+execution within the plugin is not supported. These functions are able
+to perform the global filter of a query, for example the condition
+expression in a \`WHERE\` clause or in a \`HAVING\` clause. For more details
+of the full text search based search, check out the design here: [Relevance
+Based Search With SQL/PPL Query
+Engine](https://github.com/opensearch-project/sql/issues/182)
+
+### MATCH
+
+**Description**
+
+\`match(field_expression, query_expression[, option=]*)\`
+
+The match function maps to the match query used in search engine, to
+return the documents that match a provided text, number, date or boolean
+value with a given field. Available parameters include:
+
+- analyzer
+- auto\_generate\_synonyms\_phrase
+- fuzziness
+- max\_expansions
+- prefix\_length
+- fuzzy\_transpositions
+- fuzzy\_rewrite
+- lenient
+- operator
+- minimum\_should\_match
+- zero\_terms\_query
+- boost
+
+Example with only \`field\` and \`query\` expressions, and all other
+parameters are set default values:
+
+ os> source=accounts | where match(address, 'Street') | fields lastname, address;
+ fetched rows / total rows = 2/2
+ +------------+--------------------+
+ | lastname | address |
+ |------------+--------------------|
+ | Bond | 671 Bristol Street |
+ | Bates | 789 Madison Street |
+ +------------+--------------------+
+
+Another example to show how to set custom values for the optional
+parameters:
+
+ os> source=accounts | where match(firstname, 'Hattie', operator='AND', boost=2.0) | fields lastname;
+ fetched rows / total rows = 1/1
+ +------------+
+ | lastname |
+ |------------|
+ | Bond |
+ +------------+
+
+### Limitations
+
+The full text search functions are available to execute only in OpenSearch DSL
+but not in memory as of now, so the full text search might fail for
+queries that are too complex to translate into DSL if the full text search
+function is following after a complex PPL query. To make your queries
+always work-able, it is recommended to place the full text search commands as
+close to the search command as possible, to ensure the full text search
+functions are eligible to push down. For example, a complex query like
+\`search source = people | rename firstname as name | dedup account_number | fields name, account_number, balance, employer | where match(employer, 'Open Search') | stats count() by city\`
+could fail because it is difficult to translate to DSL, but it would be
+better if we rewrite it to an equivalent query as
+\`search source = people | where match(employer, 'Open Search') | rename firstname as name | dedup account_number | fields name, account_number, balance, employer | stats count() by city\`
+by moving the where command with full text search function to the second
+command right after the search command, and the full text search would be
+optimized and executed smoothly in OpenSearch DSL. See [Optimization](https://github.com/opensearch-project/sql/blob/22924b13d9cb46759c8d213a7ce903effe06ab47/docs/user/optimization/optimization.rst)
+to get more details about the query engine optimization.
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/index.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/index.ts
new file mode 100644
index 000000000..e061c6188
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { datetimeFunction } from './datetime';
+export { conditionFunction } from './condition';
+export { mathFunction } from './math';
+export { stringFunction } from './string';
+export { fullTextSearchFunction } from './full_text_search';
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/math.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/math.ts
new file mode 100644
index 000000000..33d63f17c
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/math.ts
@@ -0,0 +1,600 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const mathFunction = `## Math
+---
+
+### ABS
+
+**Description**
+
+Usage: abs(x) calculate the abs x.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: INTEGER/LONG/FLOAT/DOUBLE
+
+Example:
+
+ os> source=people | eval \`ABS(-1)\` = ABS(-1) | fields \`ABS(-1)\`
+ fetched rows / total rows = 1/1
+ +-----------+
+ | ABS(-1) |
+ |-----------|
+ | 1 |
+ +-----------+
+
+### ACOS
+
+**Description**
+
+Usage: acos(x) calculate the arc cosine of x. Returns NULL if x is not
+in the range -1 to 1.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`ACOS(0)\` = ACOS(0) | fields \`ACOS(0)\`
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | ACOS(0) |
+ |--------------------|
+ | 1.5707963267948966 |
+ +--------------------+
+
+### ASIN
+
+**Description**
+
+Usage: asin(x) calculate the arc sine of x. Returns NULL if x is not in
+the range -1 to 1.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`ASIN(0)\` = ASIN(0) | fields \`ASIN(0)\`
+ fetched rows / total rows = 1/1
+ +-----------+
+ | ASIN(0) |
+ |-----------|
+ | 0.0 |
+ +-----------+
+
+### ATAN
+
+**Description**
+
+Usage: atan(x) calculates the arc tangent of x. atan(y, x) calculates
+the arc tangent of y / x, except that the signs of both arguments are
+used to determine the quadrant of the result.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`ATAN(2)\` = ATAN(2), \`ATAN(2, 3)\` = ATAN(2, 3) | fields \`ATAN(2)\`, \`ATAN(2, 3)\`
+ fetched rows / total rows = 1/1
+ +--------------------+--------------------+
+ | ATAN(2) | ATAN(2, 3) |
+ |--------------------+--------------------|
+ | 1.1071487177940904 | 0.5880026035475675 |
+ +--------------------+--------------------+
+
+### ATAN2
+
+**Description**
+
+Usage: atan2(y, x) calculates the arc tangent of y / x, except that the
+signs of both arguments are used to determine the quadrant of the
+result.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`ATAN2(2, 3)\` = ATAN2(2, 3) | fields \`ATAN2(2, 3)\`
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | ATAN2(2, 3) |
+ |--------------------|
+ | 0.5880026035475675 |
+ +--------------------+
+
+### CEIL
+
+**Description**
+
+Usage: ceil(x) return the smallest integer value this is greater or
+equal to x.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`CEIL(2.75)\` = CEIL(2.75) | fields \`CEIL(2.75)\`
+ fetched rows / total rows = 1/1
+ +--------------+
+ | CEIL(2.75) |
+ |--------------|
+ | 3 |
+ +--------------+
+
+### CONV
+
+**Description**
+
+Usage: CONV(x, a, b) converts the number x from a base to b base.
+
+Argument type: x: STRING, a: INTEGER, b: INTEGER
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`CONV('12', 10, 16)\` = CONV('12', 10, 16), \`CONV('2C', 16, 10)\` = CONV('2C', 16, 10), \`CONV(12, 10, 2)\` = CONV(12, 10, 2), \`CONV(1111, 2, 10)\` = CONV(1111, 2, 10) | fields \`CONV('12', 10, 16)\`, \`CONV('2C', 16, 10)\`, \`CONV(12, 10, 2)\`, \`CONV(1111, 2, 10)\`
+ fetched rows / total rows = 1/1
+ +----------------------+----------------------+-------------------+---------------------+
+ | CONV('12', 10, 16) | CONV('2C', 16, 10) | CONV(12, 10, 2) | CONV(1111, 2, 10) |
+ |----------------------+----------------------+-------------------+---------------------|
+ | c | 44 | 1100 | 15 |
+ +----------------------+----------------------+-------------------+---------------------+
+
+### COS
+
+**Description**
+
+Usage: cos(x) calculate the cosine of x, where x is given in radians.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`COS(0)\` = COS(0) | fields \`COS(0)\`
+ fetched rows / total rows = 1/1
+ +----------+
+ | COS(0) |
+ |----------|
+ | 1.0 |
+ +----------+
+
+### COT
+
+**Description**
+
+Usage: cot(x) calculate the cotangent of x. Returns out-of-range error
+if x equals to 0.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`COT(1)\` = COT(1) | fields \`COT(1)\`
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | COT(1) |
+ |--------------------|
+ | 0.6420926159343306 |
+ +--------------------+
+
+### CRC32
+
+**Description**
+
+Usage: Calculates a cyclic redundancy check value and returns a 32-bit
+unsigned value.
+
+Argument type: STRING
+
+Return type: LONG
+
+Example:
+
+ os> source=people | eval \`CRC32('MySQL')\` = CRC32('MySQL') | fields \`CRC32('MySQL')\`
+ fetched rows / total rows = 1/1
+ +------------------+
+ | CRC32('MySQL') |
+ |------------------|
+ | 3259397556 |
+ +------------------+
+
+### DEGREES
+
+**Description**
+
+Usage: degrees(x) converts x from radians to degrees.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`DEGREES(1.57)\` = DEGREES(1.57) | fields \`DEGREES(1.57)\`
+ fetched rows / total rows = 1/1
+ +-------------------+
+ | DEGREES(1.57) |
+ |-------------------|
+ | 89.95437383553924 |
+ +-------------------+
+
+### E
+
+**Description**
+
+Usage: E() returns the Euler's number
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`E()\` = E() | fields \`E()\`
+ fetched rows / total rows = 1/1
+ +-------------------+
+ | E() |
+ |-------------------|
+ | 2.718281828459045 |
+ +-------------------+
+
+### EXP
+
+**Description**
+
+Usage: exp(x) return e raised to the power of x.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`EXP(2)\` = EXP(2) | fields \`EXP(2)\`
+ fetched rows / total rows = 1/1
+ +------------------+
+ | EXP(2) |
+ |------------------|
+ | 7.38905609893065 |
+ +------------------+
+
+### FLOOR
+
+**Description**
+
+Usage: floor(x) return the largest integer value this is smaller or
+equal to x.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`FLOOR(2.75)\` = FLOOR(2.75) | fields \`FLOOR(2.75)\`
+ fetched rows / total rows = 1/1
+ +---------------+
+ | FLOOR(2.75) |
+ |---------------|
+ | 2 |
+ +---------------+
+
+### LN
+
+**Description**
+
+Usage: ln(x) return the the natural logarithm of x.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`LN(2)\` = LN(2) | fields \`LN(2)\`
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | LN(2) |
+ |--------------------|
+ | 0.6931471805599453 |
+ +--------------------+
+
+### LOG
+
+**Description**
+
+Specifications:
+
+Usage: log(x) returns the natural logarithm of x that is the base e
+logarithm of the x. log(B, x) is equivalent to log(x)/log(B).
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`LOG(2)\` = LOG(2), \`LOG(2, 8)\` = LOG(2, 8) | fields \`LOG(2)\`, \`LOG(2, 8)\`
+ fetched rows / total rows = 1/1
+ +--------------------+-------------+
+ | LOG(2) | LOG(2, 8) |
+ |--------------------+-------------|
+ | 0.6931471805599453 | 3.0 |
+ +--------------------+-------------+
+
+### LOG2
+
+**Description**
+
+Specifications:
+
+Usage: log2(x) is equivalent to log(x)/log(2).
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`LOG2(8)\` = LOG2(8) | fields \`LOG2(8)\`
+ fetched rows / total rows = 1/1
+ +-----------+
+ | LOG2(8) |
+ |-----------|
+ | 3.0 |
+ +-----------+
+
+### LOG10
+
+**Description**
+
+Specifications:
+
+Usage: log10(x) is equivalent to log(x)/log(10).
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`LOG10(100)\` = LOG10(100) | fields \`LOG10(100)\`
+ fetched rows / total rows = 1/1
+ +--------------+
+ | LOG10(100) |
+ |--------------|
+ | 2.0 |
+ +--------------+
+
+### MOD
+
+**Description**
+
+Usage: MOD(n, m) calculates the remainder of the number n divided by m.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: Wider type between types of n and m if m is nonzero value.
+If m equals to 0, then returns NULL.
+
+Example:
+
+ os> source=people | eval \`MOD(3, 2)\` = MOD(3, 2), \`MOD(3.1, 2)\` = MOD(3.1, 2) | fields \`MOD(3, 2)\`, \`MOD(3.1, 2)\`
+ fetched rows / total rows = 1/1
+ +-------------+---------------+
+ | MOD(3, 2) | MOD(3.1, 2) |
+ |-------------+---------------|
+ | 1 | 1.1 |
+ +-------------+---------------+
+
+### PI
+
+**Description**
+
+Usage: PI() returns the constant pi
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`PI()\` = PI() | fields \`PI()\`
+ fetched rows / total rows = 1/1
+ +-------------------+
+ | PI() |
+ |-------------------|
+ | 3.141592653589793 |
+ +-------------------+
+
+### POW
+
+**Description**
+
+Usage: POW(x, y) calculates the value of x raised to the power of y. Bad
+inputs return NULL result.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Synonyms: [POWER](#power)
+
+Example:
+
+ os> source=people | eval \`POW(3, 2)\` = POW(3, 2), \`POW(-3, 2)\` = POW(-3, 2), \`POW(3, -2)\` = POW(3, -2) | fields \`POW(3, 2)\`, \`POW(-3, 2)\`, \`POW(3, -2)\`
+ fetched rows / total rows = 1/1
+ +-------------+--------------+--------------------+
+ | POW(3, 2) | POW(-3, 2) | POW(3, -2) |
+ |-------------+--------------+--------------------|
+ | 9.0 | 9.0 | 0.1111111111111111 |
+ +-------------+--------------+--------------------+
+
+### POWER
+
+**Description**
+
+Usage: POWER(x, y) calculates the value of x raised to the power of y.
+Bad inputs return NULL result.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Synonyms: [POW](#pow)
+
+Example:
+
+ os> source=people | eval \`POWER(3, 2)\` = POWER(3, 2), \`POWER(-3, 2)\` = POWER(-3, 2), \`POWER(3, -2)\` = POWER(3, -2) | fields \`POWER(3, 2)\`, \`POWER(-3, 2)\`, \`POWER(3, -2)\`
+ fetched rows / total rows = 1/1
+ +---------------+----------------+--------------------+
+ | POWER(3, 2) | POWER(-3, 2) | POWER(3, -2) |
+ |---------------+----------------+--------------------|
+ | 9.0 | 9.0 | 0.1111111111111111 |
+ +---------------+----------------+--------------------+
+
+### RADIANS
+
+**Description**
+
+Usage: radians(x) converts x from degrees to radians.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`RADIANS(90)\` = RADIANS(90) | fields \`RADIANS(90)\`
+ fetched rows / total rows = 1/1
+ +--------------------+
+ | RADIANS(90) |
+ |--------------------|
+ | 1.5707963267948966 |
+ +--------------------+
+
+### RAND
+
+**Description**
+
+Usage: RAND()/RAND(N) returns a random floating-point value in the range
+0 <= value < 1.0. If integer N is specified, the seed is
+initialized prior to execution. One implication of this behavior is with
+identical argument N, rand(N) returns the same value each time, and thus
+produces a repeatable sequence of column values.
+
+Argument type: INTEGER
+
+Return type: FLOAT
+
+Example:
+
+ os> source=people | eval \`RAND(3)\` = RAND(3) | fields \`RAND(3)\`
+ fetched rows / total rows = 1/1
+ +------------+
+ | RAND(3) |
+ |------------|
+ | 0.73105735 |
+ +------------+
+
+### ROUND
+
+**Description**
+
+Usage: ROUND(x, d) rounds the argument x to d decimal places, d defaults
+to 0 if not specified
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type map:
+
+(INTEGER/LONG \[,INTEGER\]) -> LONG (FLOAT/DOUBLE \[,INTEGER\]) ->
+LONG
+
+Example:
+
+ os> source=people | eval \`ROUND(12.34)\` = ROUND(12.34), \`ROUND(12.34, 1)\` = ROUND(12.34, 1), \`ROUND(12.34, -1)\` = ROUND(12.34, -1), \`ROUND(12, 1)\` = ROUND(12, 1) | fields \`ROUND(12.34)\`, \`ROUND(12.34, 1)\`, \`ROUND(12.34, -1)\`, \`ROUND(12, 1)\`
+ fetched rows / total rows = 1/1
+ +----------------+-------------------+--------------------+----------------+
+ | ROUND(12.34) | ROUND(12.34, 1) | ROUND(12.34, -1) | ROUND(12, 1) |
+ |----------------+-------------------+--------------------+----------------|
+ | 12.0 | 12.3 | 10.0 | 12 |
+ +----------------+-------------------+--------------------+----------------+
+
+### SIGN
+
+**Description**
+
+Usage: Returns the sign of the argument as -1, 0, or 1, depending on
+whether the number is negative, zero, or positive
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`SIGN(1)\` = SIGN(1), \`SIGN(0)\` = SIGN(0), \`SIGN(-1.1)\` = SIGN(-1.1) | fields \`SIGN(1)\`, \`SIGN(0)\`, \`SIGN(-1.1)\`
+ fetched rows / total rows = 1/1
+ +-----------+-----------+--------------+
+ | SIGN(1) | SIGN(0) | SIGN(-1.1) |
+ |-----------+-----------+--------------|
+ | 1 | 0 | -1 |
+ +-----------+-----------+--------------+
+
+### SIN
+
+**Description**
+
+Usage: sin(x) calculate the sine of x, where x is given in radians.
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type: DOUBLE
+
+Example:
+
+ os> source=people | eval \`SIN(0)\` = SIN(0) | fields \`SIN(0)\`
+ fetched rows / total rows = 1/1
+ +----------+
+ | SIN(0) |
+ |----------|
+ | 0.0 |
+ +----------+
+
+### SQRT
+
+**Description**
+
+Usage: Calculates the square root of a non-negative number
+
+Argument type: INTEGER/LONG/FLOAT/DOUBLE
+
+Return type map:
+
+(Non-negative) INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE (Negative)
+INTEGER/LONG/FLOAT/DOUBLE -> NULL
+
+Example:
+
+ os> source=people | eval \`SQRT(4)\` = SQRT(4), \`SQRT(4.41)\` = SQRT(4.41) | fields \`SQRT(4)\`, \`SQRT(4.41)\`
+ fetched rows / total rows = 1/1
+ +-----------+--------------+
+ | SQRT(4) | SQRT(4.41) |
+ |-----------+--------------|
+ | 2.0 | 2.1 |
+ +-----------+--------------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/functions/string.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/string.ts
new file mode 100644
index 000000000..824727ae8
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/functions/string.ts
@@ -0,0 +1,240 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const stringFunction = `## String
+---
+
+### CONCAT
+
+**Description**
+
+Usage: CONCAT(str1, str2) returns str1 and str strings concatenated
+together.
+
+Argument type: STRING, STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`CONCAT('hello', 'world')\` = CONCAT('hello', 'world') | fields \`CONCAT('hello', 'world')\`
+ fetched rows / total rows = 1/1
+ +----------------------------+
+ | CONCAT('hello', 'world') |
+ |----------------------------|
+ | helloworld |
+ +----------------------------+
+
+### CONCAT\_WS
+
+**Description**
+
+Usage: CONCAT\_WS(sep, str1, str2) returns str1 concatenated with str2
+using sep as a separator between them.
+
+Argument type: STRING, STRING, STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`CONCAT_WS(',', 'hello', 'world')\` = CONCAT_WS(',', 'hello', 'world') | fields \`CONCAT_WS(',', 'hello', 'world')\`
+ fetched rows / total rows = 1/1
+ +------------------------------------+
+ | CONCAT_WS(',', 'hello', 'world') |
+ |------------------------------------|
+ | hello,world |
+ +------------------------------------+
+
+### LENGTH
+
+**Description**
+
+Specifications:
+
+1. LENGTH(STRING) -> INTEGER
+
+Usage: length(str) returns length of string measured in bytes.
+
+Argument type: STRING
+
+Return type: INTEGER
+
+Example:
+
+ os> source=people | eval \`LENGTH('helloworld')\` = LENGTH('helloworld') | fields \`LENGTH('helloworld')\`
+ fetched rows / total rows = 1/1
+ +------------------------+
+ | LENGTH('helloworld') |
+ |------------------------|
+ | 10 |
+ +------------------------+
+
+### LIKE
+
+**Description**
+
+Usage: like(string, PATTERN) return true if the string match the
+PATTERN.
+
+There are two wildcards often used in conjunction with the LIKE
+operator:
+
+- \`%\` - The percent sign represents zero, one, or multiple characters
+- \`_\` - The underscore represents a single character
+
+Example:
+
+ os> source=people | eval \`LIKE('hello world', '_ello%')\` = LIKE('hello world', '_ello%') | fields \`LIKE('hello world', '_ello%')\`
+ fetched rows / total rows = 1/1
+ +---------------------------------+
+ | LIKE('hello world', '_ello%') |
+ |---------------------------------|
+ | True |
+ +---------------------------------+
+
+### LOWER
+
+**Description**
+
+Usage: lower(string) converts the string to lowercase.
+
+Argument type: STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`LOWER('helloworld')\` = LOWER('helloworld'), \`LOWER('HELLOWORLD')\` = LOWER('HELLOWORLD') | fields \`LOWER('helloworld')\`, \`LOWER('HELLOWORLD')\`
+ fetched rows / total rows = 1/1
+ +-----------------------+-----------------------+
+ | LOWER('helloworld') | LOWER('HELLOWORLD') |
+ |-----------------------+-----------------------|
+ | helloworld | helloworld |
+ +-----------------------+-----------------------+
+
+### LTRIM
+
+**Description**
+
+Usage: ltrim(str) trims leading space characters from the string.
+
+Argument type: STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`LTRIM(' hello')\` = LTRIM(' hello'), \`LTRIM('hello ')\` = LTRIM('hello ') | fields \`LTRIM(' hello')\`, \`LTRIM('hello ')\`
+ fetched rows / total rows = 1/1
+ +---------------------+---------------------+
+ | LTRIM(' hello') | LTRIM('hello ') |
+ |---------------------+---------------------|
+ | hello | hello |
+ +---------------------+---------------------+
+
+### RIGHT
+
+**Description**
+
+Usage: right(str, len) returns the rightmost len characters from the
+string str, or NULL if any argument is NULL.
+
+Argument type: STRING, INTEGER
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`RIGHT('helloworld', 5)\` = RIGHT('helloworld', 5), \`RIGHT('HELLOWORLD', 0)\` = RIGHT('HELLOWORLD', 0) | fields \`RIGHT('helloworld', 5)\`, \`RIGHT('HELLOWORLD', 0)\`
+ fetched rows / total rows = 1/1
+ +--------------------------+--------------------------+
+ | RIGHT('helloworld', 5) | RIGHT('HELLOWORLD', 0) |
+ |--------------------------+--------------------------|
+ | world | |
+ +--------------------------+--------------------------+
+
+### RTRIM
+
+**Description**
+
+Usage: rtrim(str) trims trailing space characters from the string.
+
+Argument type: STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`RTRIM(' hello')\` = RTRIM(' hello'), \`RTRIM('hello ')\` = RTRIM('hello ') | fields \`RTRIM(' hello')\`, \`RTRIM('hello ')\`
+ fetched rows / total rows = 1/1
+ +---------------------+---------------------+
+ | RTRIM(' hello') | RTRIM('hello ') |
+ |---------------------+---------------------|
+ | hello | hello |
+ +---------------------+---------------------+
+
+### SUBSTRING
+
+**Description**
+
+Usage: substring(str, start) or substring(str, start, length) returns
+substring using start and length. With no length, entire string from
+start is returned.
+
+Argument type: STRING, INTEGER, INTEGER
+
+Return type: STRING
+
+Synonyms: SUBSTR
+
+Example:
+
+ os> source=people | eval \`SUBSTRING('helloworld', 5)\` = SUBSTRING('helloworld', 5), \`SUBSTRING('helloworld', 5, 3)\` = SUBSTRING('helloworld', 5, 3) | fields \`SUBSTRING('helloworld', 5)\`, \`SUBSTRING('helloworld', 5, 3)\`
+ fetched rows / total rows = 1/1
+ +------------------------------+---------------------------------+
+ | SUBSTRING('helloworld', 5) | SUBSTRING('helloworld', 5, 3) |
+ |------------------------------+---------------------------------|
+ | oworld | owo |
+ +------------------------------+---------------------------------+
+
+### TRIM
+
+**Description**
+
+Argument Type: STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`TRIM(' hello')\` = TRIM(' hello'), \`TRIM('hello ')\` = TRIM('hello ') | fields \`TRIM(' hello')\`, \`TRIM('hello ')\`
+ fetched rows / total rows = 1/1
+ +--------------------+--------------------+
+ | TRIM(' hello') | TRIM('hello ') |
+ |--------------------+--------------------|
+ | hello | hello |
+ +--------------------+--------------------+
+
+### UPPER
+
+**Description**
+
+Usage: upper(string) converts the string to uppercase.
+
+Argument type: STRING
+
+Return type: STRING
+
+Example:
+
+ os> source=people | eval \`UPPER('helloworld')\` = UPPER('helloworld'), \`UPPER('HELLOWORLD')\` = UPPER('HELLOWORLD') | fields \`UPPER('helloworld')\`, \`UPPER('HELLOWORLD')\`
+ fetched rows / total rows = 1/1
+ +-----------------------+-----------------------+
+ | UPPER('helloworld') | UPPER('HELLOWORLD') |
+ |-----------------------+-----------------------|
+ | HELLOWORLD | HELLOWORLD |
+ +-----------------------+-----------------------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/groups.tsx b/dashboards-observability/public/components/common/helpers/ppl_docs/groups.tsx
new file mode 100644
index 000000000..633def301
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/groups.tsx
@@ -0,0 +1,126 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ dedupCmd,
+ evalCmd,
+ fieldsCmd,
+ headCmd,
+ parseCmd,
+ rareCmd,
+ renameCmd,
+ searchCmd,
+ sortCmd,
+ statsCmd,
+ syntaxCmd,
+ topCmd,
+ whereCmd,
+} from './commands';
+import {
+ mathFunction,
+ datetimeFunction,
+ stringFunction,
+ conditionFunction,
+ fullTextSearchFunction,
+} from './functions';
+import { pplDatatypes, pplIdentifiers } from './language_structure';
+
+export const Group1 = {
+ label: 'Commands',
+ options: [
+ {
+ label: 'Syntax',
+ value: syntaxCmd,
+ },
+ {
+ label: 'dedup',
+ value: dedupCmd,
+ },
+ {
+ label: 'eval',
+ value: evalCmd,
+ },
+ {
+ label: 'fields',
+ value: fieldsCmd,
+ },
+ {
+ label: 'rename',
+ value: renameCmd,
+ },
+ {
+ label: 'search',
+ value: searchCmd,
+ },
+ {
+ label: 'sort',
+ value: sortCmd,
+ },
+ {
+ label: 'stats',
+ value: statsCmd,
+ },
+ {
+ label: 'where',
+ value: whereCmd,
+ },
+ {
+ label: 'head',
+ value: headCmd,
+ },
+ {
+ label: 'parse',
+ value: parseCmd,
+ },
+ {
+ label: 'rare',
+ value: rareCmd,
+ },
+ {
+ label: 'top',
+ value: topCmd,
+ },
+ ],
+};
+
+export const Group2 = {
+ label: 'Functions',
+ options: [
+ {
+ label: 'Math',
+ value: mathFunction,
+ },
+ {
+ label: 'Date and Time',
+ value: datetimeFunction,
+ },
+ {
+ label: 'String',
+ value: stringFunction,
+ },
+ {
+ label: 'Condition',
+ value: conditionFunction,
+ },
+ {
+ label: 'Full Text Search',
+ value: fullTextSearchFunction,
+ },
+ ],
+};
+
+export const Group3 = {
+ label: 'Language Structure',
+ options: [
+ {
+ label: 'Identifiers',
+ value: pplIdentifiers,
+ },
+ {
+ label: 'Data Types',
+ value: pplDatatypes,
+ },
+ ],
+};
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/datatypes.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/datatypes.ts
new file mode 100644
index 000000000..b01149143
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/datatypes.ts
@@ -0,0 +1,412 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const pplDatatypes = `## Data Types
+---
+### **Overview**
+
+### PPL Data Types
+
+The PPL support the following data types.
+
+| PPL Data Type |
+|---------------|
+| boolean |
+| byte |
+| short |
+| integer |
+| long |
+| float |
+| double |
+| string |
+| text |
+| timestamp |
+| datetime |
+| date |
+| time |
+| interval |
+| ip |
+| geo\_point |
+| binary |
+| struct |
+| array |
+
+### Data Types Mapping
+
+The table below list the mapping between OpenSearch Data Type, PPL Data
+Type and SQL Type.
+
+| OpenSearch Type | PPL Type | SQL Type |
+|-----------------|-----------|-----------|
+| boolean | boolean | BOOLEAN |
+| byte | byte | TINYINT |
+| short | byte | SMALLINT |
+| integer | integer | INTEGER |
+| long | long | BIGINT |
+| float | float | REAL |
+| half\_float | float | FLOAT |
+| scaled\_float | float | DOUBLE |
+| double | double | DOUBLE |
+| keyword | string | VARCHAR |
+| text | text | VARCHAR |
+| date | timestamp | TIMESTAMP |
+| ip | ip | VARCHAR |
+| date | timestamp | TIMESTAMP |
+| binary | binary | VARBINARY |
+| object | struct | STRUCT |
+| nested | array | STRUCT |
+
+Notes: Not all the PPL Type has correspond OpenSearch Type. e.g. data
+and time. To use function which required such data type, user should
+explict convert the data type.
+
+### **Numeric Data Types**
+
+Numeric values ranged from -2147483648 to +2147483647 are recognized as
+integer with type name \`INTEGER\`. For others outside the range, \`LONG\`
+integer will be the data type after parsed.
+
+### **Date and Time Data Types**
+
+The date and time data types are the types that represent temporal
+values and PPL plugin supports types including DATE, TIME, DATETIME,
+TIMESTAMP and INTERVAL. By default, the OpenSearch DSL uses date type as
+the only date and time related type, which has contained all information
+about an absolute time point. To integrate with PPL language, each of
+the types other than timestamp is holding part of temporal or timezone
+information, and the usage to explicitly clarify the date and time types
+is reflected in the datetime functions (see [Functions](functions.rst)
+for details), where some functions might have restrictions in the input
+argument type.
+
+#### **Date**
+
+Date represents the calendar date regardless of the time zone. A given
+date value represents a 24-hour period, or say a day, but this period
+varies in different timezones and might have flexible hours during
+Daylight Savings Time programs. Besides, the date type does not contain
+time information as well. The supported range is '1000-01-01' to
+'9999-12-31'.
+
+| Type | Syntax | Range |
+|------|--------------|------------------------------|
+| Date | 'yyyy-MM-dd' | '0001-01-01' to '9999-12-31' |
+
+#### **Time**
+
+Time represents the time on the clock or watch with no regard for which
+timezone it might be related with. Time type data does not have date
+information.
+
+| Type | Syntax | Range |
+|------|-------------------------|----------------------------------------|
+| Time | 'hh:mm:ss\[.fraction\]' | '00:00:00.000000' to '23:59:59.999999' |
+
+#### **Datetime**
+
+Datetime type is the combination of date and time. The conversion rule
+of date or time to datetime is described in [Conversion between date and
+time types](#conversion-between-date-and-time-types). Datetime type does
+not contain timezone information. For an absolute time point that
+contains both date time and timezone information, see
+[Timestamp](#timestamp).
+
+| Type | Syntax | Range |
+|----------|------------------------------------|--------------------------------------------------------------|
+| Datetime | 'yyyy-MM-dd hh:mm:ss\[.fraction\]' | '0001-01-01 00:00:00.000000' to '9999-12-31 23:59:59.999999' |
+
+#### **Timestamp**
+
+A timestamp instance is an absolute instant independent of timezone or
+convention. For example, for a given point of time, if we set the
+timestamp of this time point into another timezone, the value should
+also be different accordingly. Besides, the storage of timestamp type is
+also different from the other types. The timestamp is converted from the
+current timezone to UTC for storage, and is converted back to the set
+timezone from UTC when retrieving.
+
+| Type | Syntax | Range |
+|-----------|------------------------------------|------------------------------------------------------------------|
+| Timestamp | 'yyyy-MM-dd hh:mm:ss\[.fraction\]' | '0001-01-01 00:00:01.000000' UTC to '9999-12-31 23:59:59.999999' |
+
+#### **Interval**
+
+Interval data type represents a temporal duration or a period. The
+syntax is as follows:
+
+| Type | Syntax |
+|----------|--------------------|
+| Interval | INTERVAL expr unit |
+
+The expr is any expression that can be iterated to a quantity value
+eventually, see [Expressions](expressions.rst) for details. The unit
+represents the unit for interpreting the quantity, including
+MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER and
+YEAR.The INTERVAL keyword and the unit specifier are not case sensitive.
+Note that there are two classes of intervals. Year-week intervals can
+store years, quarters, months and weeks. Day-time intervals can store
+days, hours, minutes, seconds and microseconds. Year-week intervals are
+comparable only with another year-week intervals. These two types of
+intervals can only comparable with the same type of themselves.
+
+### **Conversion between date and time types**
+
+Basically the date and time types except interval can be converted to
+each other, but might suffer some alteration of the value or some
+information loss, for example extracting the time value from a datetime
+value, or convert a date value to a datetime value and so forth. Here
+lists the summary of the conversion rules that PPL plugin supports for
+each of the types:
+
+#### **Conversion from DATE**
+
+- Since the date value does not have any time information, conversion
+ to [Time](#time) type is not useful, and will always return a zero
+ time value '00:00:00'.
+- Conversion from date to datetime has a data fill-up due to the lack
+ of time information, and it attaches the time '00:00:00' to the
+ original date by default and forms a datetime instance. For example,
+ the result to covert date '2020-08-17' to datetime type is datetime
+ '2020-08-17 00:00:00'.
+- Conversion to timestamp is to alternate both the time value and the
+ timezone information, and it attaches the zero time value '00:00:00'
+ and the session timezone (UTC by default) to the date. For example,
+ the result to covert date '2020-08-17' to datetime type with session
+ timezone UTC is datetime '2020-08-17 00:00:00' UTC.
+
+#### **Conversion from TIME**
+
+- Time value cannot be converted to any other date and time types
+ since it does not contain any date information, so it is not
+ meaningful to give no date info to a date/datetime/timestamp
+ instance.
+
+#### **Conversion from DATETIME**
+
+- Conversion from datetime to date is to extract the date part from
+ the datetime value. For example, the result to convert datetime
+ '2020-08-17 14:09:00' to date is date '2020-08-08'.
+- Conversion to time is to extract the time part from the datetime
+ value. For example, the result to convert datetime '2020-08-17
+ 14:09:00' to time is time '14:09:00'.
+- Since the datetime type does not contain timezone information, the
+ conversion to timestamp needs to fill up the timezone part with the
+ session timezone. For example, the result to convert datetime
+ '2020-08-17 14:09:00' with system timezone of UTC, to timestamp is
+ timestamp '2020-08-17 14:09:00' UTC.
+
+#### **Conversion from TIMESTAMP**
+
+- Conversion from timestamp is much more straightforward. To convert
+ it to date is to extract the date value, and conversion to time is
+ to extract the time value. Conversion to datetime, it will extracts
+ the datetime value and leave the timezone information over. For
+ example, the result to convert datetime '2020-08-17 14:09:00' UTC to
+ date is date '2020-08-17', to time is '14:09:00' and to datetime is
+ datetime '2020-08-17 14:09:00'.
+
+### **String Data Types**
+
+A string is a sequence of characters enclosed in either single or double
+quotes. For example, both 'text' and "text" will be treated as string
+literal.
+
+### **Query Struct Data Types**
+
+In PPL, the Struct Data Types corresponding to the [Object field type in
+OpenSearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/object.html).
+The "." is used as the path selector when access the inner attribute of
+the struct data.
+
+#### **Example: People**
+
+There are three fields in test index \`people\`: 1) deep nested object
+field \`city\`; 2) object field of array value \`account\`; 3) nested field
+\`projects\`:
+
+ {
+ "mappings": {
+ "properties": {
+ "city": {
+ "properties": {
+ "name": {
+ "type": "keyword"
+ },
+ "location": {
+ "properties": {
+ "latitude": {
+ "type": "double"
+ }
+ }
+ }
+ }
+ },
+ "account": {
+ "properties": {
+ "id": {
+ "type": "keyword"
+ }
+ }
+ },
+ "projects": {
+ "type": "nested",
+ "properties": {
+ "name": {
+ "type": "keyword"
+ }
+ }
+ }
+ }
+ }
+ }
+
+#### **Example: Employees**
+
+Here is the mapping for test index \`employees_nested\`. Note that field
+\`projects\` is a nested field:
+
+ {
+ "mappings": {
+ "properties": {
+ "id": {
+ "type": "long"
+ },
+ "name": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ },
+ "projects": {
+ "type": "nested",
+ "properties": {
+ "name": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ },
+ "fielddata": true
+ },
+ "started_year": {
+ "type": "long"
+ }
+ }
+ },
+ "title": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ }
+ }
+ }
+ }
+
+Result set:
+
+ {
+ "employees_nested" : [
+ {
+ "id" : 3,
+ "name" : "Bob Smith",
+ "title" : null,
+ "projects" : [
+ {
+ "name" : "AWS Redshift Spectrum querying",
+ "started_year" : 1990
+ },
+ {
+ "name" : "AWS Redshift security",
+ "started_year" : 1999
+ },
+ {
+ "name" : "AWS Aurora security",
+ "started_year" : 2015
+ }
+ ]
+ },
+ {
+ "id" : 4,
+ "name" : "Susan Smith",
+ "title" : "Dev Mgr",
+ "projects" : [ ]
+ },
+ {
+ "id" : 6,
+ "name" : "Jane Smith",
+ "title" : "Software Eng 2",
+ "projects" : [
+ {
+ "name" : "AWS Redshift security",
+ "started_year" : 1998
+ },
+ {
+ "name" : "AWS Hello security",
+ "started_year" : 2015,
+ "address" : [
+ {
+ "city" : "Dallas",
+ "state" : "TX"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+#### **Example 1: Select struct inner attribute**
+
+The example show fetch city (top level), city.name (second level),
+city.location.latitude (deeper level) struct type data from people
+results.
+
+PPL query:
+
+ os> source=people | fields city, city.name, city.location.latitude;
+ fetched rows / total rows = 1/1
+ +-----------------------------------------------------+-------------+--------------------------+
+ | city | city.name | city.location.latitude |
+ |-----------------------------------------------------+-------------+--------------------------|
+ | {'name': 'Seattle', 'location': {'latitude': 10.5}} | Seattle | 10.5 |
+ +-----------------------------------------------------+-------------+--------------------------+
+
+#### **Example 2: Group by struct inner attribute**
+
+The example show group by object field inner attribute.
+
+PPL query:
+
+ os> source=people | stats count() by city.name;
+ fetched rows / total rows = 1/1
+ +-----------+-------------+
+ | count() | city.name |
+ |-----------+-------------|
+ | 1 | Seattle |
+ +-----------+-------------+
+
+#### **Example 3: Selecting Field of Array Value**
+
+Select deeper level for object fields of array value which returns the
+first element in the array. For example, because inner field
+\`accounts.id\` has three values instead of a tuple in this document, the
+first entry is returned.:
+
+ os> source = people | fields accounts, accounts.id;
+ fetched rows / total rows = 1/1
+ +------------+---------------+
+ | accounts | accounts.id |
+ |------------+---------------|
+ | {'id': 1} | 1 |
+ +------------+---------------+
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/identifiers.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/identifiers.ts
new file mode 100644
index 000000000..e52037913
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/identifiers.ts
@@ -0,0 +1,107 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const pplIdentifiers = `## Indentifiers
+---
+
+### **Introduction**
+
+Identifiers are used for naming your database objects, such as index
+name, field name, alias etc. Basically there are two types of
+identifiers: regular identifiers and delimited identifiers.
+
+### **Regular Identifiers**
+
+**Description**
+
+A regular identifier is a string of characters that must start with
+ASCII letter (lower or upper case). The subsequent character can be a
+combination of letter, digit, underscore (\`_\`). It cannot be a reversed
+key word. And whitespace and other special characters are not allowed.
+
+For OpenSearch, the following identifiers are supported extensionally:
+
+1. Identifiers prefixed by dot \`.\`: this is called hidden index in
+ OpenSearch, for example \`.opensearch_dashboards\`.
+2. Identifiers prefixed by at sign \`@\`: this is common for meta fields
+ generated in Logstash ingestion.
+3. Identifiers with \`-\` in the middle: this is mostly the case for
+ index name with date information.
+4. Identifiers with star \`*\` present: this is mostly an index pattern
+ for wildcard match.
+
+Index name with date suffix separated by dash or dots, such as
+\`cwl-2020.01.11\` or \`logs-7.0-2020.01.11\`, is common for those created
+by Logstash or FileBeat ingestion. So, this kind of identifier used as
+index name is also supported without the need of being quoted for user
+convenience. In this case, wildcard within date pattern is also allowed
+to search for data across indices of different date range. For example,
+you can use \`logs-2020.1*\` to search in indices for October, November
+and December 2020.
+
+#### **Examples**
+
+Here are examples for using index pattern directly without quotes:
+
+ os> source=accounts | fields account_number, firstname, lastname;
+ fetched rows / total rows = 4/4
+ +------------------+-------------+------------+
+ | account_number | firstname | lastname |
+ |------------------+-------------+------------|
+ | 1 | Amber | Duke |
+ | 6 | Hattie | Bond |
+ | 13 | Nanette | Bates |
+ | 18 | Dale | Adams |
+ +------------------+-------------+------------+
+
+### **Delimited Identifiers**
+
+**Description**
+
+A delimited identifier is an identifier enclosed in back ticks \`\`. In
+this case, the identifier enclosed is not necessarily a regular
+identifier. In other words, it can contain any special character not
+allowed by regular identifier.
+
+#### **Use Cases**
+
+Here are typical examples of the use of delimited identifiers:
+
+1. Identifiers of reserved key word name
+2. Identifiers with dot \`.\` present: similarly as \`-\` in index name to
+ include date information, it is required to be quoted so parser can
+ differentiate it from identifier with qualifiers.
+3. Identifiers with other special character: OpenSearch has its own
+ rule which allows more special character, for example Unicode
+ character is supported in index name.
+
+#### **Examples**
+
+Here are examples for quoting an index name by back ticks:
+
+ os> source=\`accounts\` | fields \`account_number\`;
+ fetched rows / total rows = 4/4
+ +------------------+
+ | account_number |
+ |------------------|
+ | 1 |
+ | 6 |
+ | 13 |
+ | 18 |
+ +------------------+
+
+### **Case Sensitivity**
+
+**Description**
+
+Identifiers are treated in case sensitive manner. So it must be exactly
+same as what is stored in OpenSearch.
+
+### **Examples**
+
+For example, if you run \`source=Accounts\`, it will end up with an index
+not found exception from our plugin because the actual index name is
+under lower case.
+`
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/index.ts b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/index.ts
new file mode 100644
index 000000000..34ab26c26
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/language_structure/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export {pplDatatypes} from './datatypes';
+export {pplIdentifiers} from './identifiers';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/helpers/ppl_docs/overview.tsx b/dashboards-observability/public/components/common/helpers/ppl_docs/overview.tsx
new file mode 100644
index 000000000..0bb3bd71f
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_docs/overview.tsx
@@ -0,0 +1,41 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const overview = `## Overview
+---
+Piped Processing Language (PPL), powered by OpenSearch, enables
+OpenSearch users with exploration and discovery of, and finding search
+patterns in data stored in OpenSearch, using a set of commands delimited
+by pipes (\|). These are essentially read-only requests to process data
+and return results.
+
+Currently, OpenSearch users can query data using either Query DSL or
+SQL. Query DSL is powerful and fast. However, it has a steep learning
+curve, and was not designed as a human interface to easily create ad hoc
+queries and explore user data. SQL allows users to extract and analyze
+data in OpenSearch in a declarative manner. OpenSearch now makes its
+search and query engine robust by introducing Piped Processing Language
+(PPL). It enables users to extract insights from OpenSearch with a
+sequence of commands delimited by pipes () syntax. It enables
+developers, DevOps engineers, support engineers, site reliability
+engineers (SREs), and IT managers to effectively discover and explore
+log, monitoring and observability data stored in OpenSearch.
+
+We expand the capabilities of our Workbench, a comprehensive and
+integrated visual query tool currently supporting only SQL, to run
+on-demand PPL commands, and view and save results as text and JSON. We
+also add a new interactive standalone command line tool, the PPL CLI, to
+run on-demand PPL commands, and view and save results as text and JSON.
+
+The query start with search command and then flowing a set of command
+delimited by pipe ( for example, the following query retrieve firstname
+and lastname from accounts if age large than 18.
+
+\`\`\`
+source=accounts
+| where age > 18
+| fields firstname, lastname
+\`\`\`
+`;
diff --git a/dashboards-observability/public/components/common/helpers/ppl_reference_flyout.tsx b/dashboards-observability/public/components/common/helpers/ppl_reference_flyout.tsx
new file mode 100644
index 000000000..bf5e52261
--- /dev/null
+++ b/dashboards-observability/public/components/common/helpers/ppl_reference_flyout.tsx
@@ -0,0 +1,102 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiComboBox,
+ EuiComboBoxOptionOption,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFlyoutBody,
+ EuiFlyoutFooter,
+ EuiFlyoutHeader,
+ EuiLink,
+ EuiMarkdownFormat,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import { PPL_DOCUMENTATION_URL } from '../../../../common/constants/shared';
+import _ from 'lodash';
+import React, { useState } from 'react';
+import { FlyoutContainers } from '../flyout_containers';
+import { Group1, Group2, Group3 } from './ppl_docs/groups';
+import { overview } from './ppl_docs/overview';
+
+type Props = {
+ module: string;
+ closeFlyout: () => void;
+};
+
+export const PPLReferenceFlyout = ({ module, closeFlyout }: Props) => {
+ const allOptionsStatic = [{ label: 'Overview', value: overview }, Group1, Group2, Group3];
+ const defaultOption =
+ module === 'explorer' ? [allOptionsStatic[0]] : [_.find(Group1.options, ['label', 'where'])];
+ const [selectedOptions, setSelected] = useState(defaultOption);
+ const [flyoutContent, setFlyoutContent] = useState(
+ {defaultOption[0].value}
+ );
+
+ const onChange = (selectedOptions: any) => {
+ setSelected(selectedOptions);
+
+ const newContent = selectedOptions.map((option: EuiComboBoxOptionOption) => (
+ {option.value}
+ ));
+ setFlyoutContent(newContent);
+ };
+
+ const flyoutHeader = (
+
+
+ OpenSearch PPL Reference Manual
+
+
+ );
+
+ const flyoutBody = (
+
+
+
+
+
+
+
+
+ Learn More
+
+
+
+
+
+ {flyoutContent}
+
+ );
+
+ const flyoutFooter = (
+
+
+
+ Close
+
+
+
+ );
+
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/live_tail/__tests__/__snapshots__/live_tail_button.test.tsx.snap b/dashboards-observability/public/components/common/live_tail/__tests__/__snapshots__/live_tail_button.test.tsx.snap
new file mode 100644
index 000000000..8eda93631
--- /dev/null
+++ b/dashboards-observability/public/components/common/live_tail/__tests__/__snapshots__/live_tail_button.test.tsx.snap
@@ -0,0 +1,254 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Live tail button change live tail to 10s interval 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10s
+
+
+
+
+
+
+
+`;
+
+exports[`Live tail button starts live tail with 5s interval 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ 5s
+
+
+
+
+
+
+
+`;
+
+exports[`Live tail off button stop live tail 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Stop
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/common/live_tail/__tests__/live_tail_button.test.tsx b/dashboards-observability/public/components/common/live_tail/__tests__/live_tail_button.test.tsx
new file mode 100644
index 000000000..4cb2a478f
--- /dev/null
+++ b/dashboards-observability/public/components/common/live_tail/__tests__/live_tail_button.test.tsx
@@ -0,0 +1,75 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { LiveTailButton, StopLiveButton } from '../live_tail_button';
+import { waitFor } from '@testing-library/dom';
+
+ describe('Live tail button', () => {
+ configure({ adapter: new Adapter() });
+
+ it('starts live tail with 5s interval', async () => {
+ const setIsLiveTailPopoverOpen = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('change live tail to 10s interval', async () => {
+ const setIsLiveTailPopoverOpen = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+ });
+
+ describe('Live tail off button', () => {
+ configure({ adapter: new Adapter() });
+
+ it('stop live tail', async () => {
+ const StopLive = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+ });
\ No newline at end of file
diff --git a/dashboards-observability/public/components/common/live_tail/live_tail_button.tsx b/dashboards-observability/public/components/common/live_tail/live_tail_button.tsx
new file mode 100644
index 000000000..0e53152fa
--- /dev/null
+++ b/dashboards-observability/public/components/common/live_tail/live_tail_button.tsx
@@ -0,0 +1,55 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+//Define pop over interval options for live tail button in your plugin
+
+import { EuiButton } from "@elastic/eui";
+import React, { useMemo } from "react";
+import { LiveTailProps } from "common/types/explorer";
+
+//Live Tail Button
+export const LiveTailButton = ({
+ isLiveTailOn,
+ isLiveTailPopoverOpen,
+ setIsLiveTailPopoverOpen,
+ liveTailName,
+ dataTestSubj,
+}: LiveTailProps) => {
+ const liveButton = useMemo(() => {
+ return (
+ setIsLiveTailPopoverOpen(!isLiveTailPopoverOpen)}
+ data-test-subj={dataTestSubj}
+ >
+ {liveTailName}
+
+ );
+ }, [isLiveTailPopoverOpen, isLiveTailOn]);
+ return liveButton;
+};
+
+export const StopLiveButton = (props: any) => {
+ const { StopLive, dataTestSubj } = props;
+
+ const stopButton = () => {
+ return (
+ StopLive()}
+ color="danger"
+ data-test-subj={dataTestSubj}
+ >
+ Stop
+
+ );
+ };
+ return stopButton();
+};
+
+export const sleep = (milliseconds: number | undefined) => {
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
+};
diff --git a/dashboards-observability/public/components/common/search/autocomplete.test.tsx b/dashboards-observability/public/components/common/search/autocomplete.test.tsx
new file mode 100644
index 000000000..fd5017101
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/autocomplete.test.tsx
@@ -0,0 +1,733 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import DSLService from 'public/services/requests/dsl';
+import React from 'react';
+import { Autocomplete } from './autocomplete';
+import { parseGetSuggestions } from './autocomplete_logic';
+import {
+ AutocompleteItem,
+ pipeCommands,
+ statsCommands,
+} from '../../../../common/constants/autocomplete';
+import { act } from 'react-dom/test-utils';
+
+configure({ adapter: new Adapter() });
+
+describe('renders autocomplete', function () {
+ const query = '';
+ const tempQuery = '';
+ const handleQueryChange = jest.fn();
+ const handleQuerySearch = jest.fn();
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest.fn(),
+ fetchIndices: jest.fn(),
+ fetchFields: jest.fn(),
+ } as unknown) as DSLService;
+ const getSuggestions = jest.fn();
+ const onItemSelect = jest.fn();
+ const utils = render(
+
+ );
+
+ const searchBar = utils.getByPlaceholderText('Enter PPL query');
+
+ it('handles query change', () => {
+ act(() => {
+ fireEvent.change(searchBar, { target: { value: 'new query' } });
+ });
+ expect(handleQueryChange).toBeCalledWith('new query');
+ });
+
+ it('handles query search on shift enter', () => {
+ act(() => {
+ fireEvent.keyDown(searchBar, { keyCode: 13, shiftKey: true });
+ });
+ expect(handleQuerySearch).toBeCalled();
+ });
+});
+
+describe('autocomplete logic', function () {
+ const dslService = ({
+ http: jest.fn(),
+ fetch: jest
+ .fn()
+ .mockReturnValueOnce({
+ aggregations: { top_tags: { buckets: [{ key: 'data', doc_count: 1 }] } },
+ })
+ .mockReturnValueOnce({
+ aggregations: {
+ top_tags: {
+ buckets: [
+ { key: 1, doc_count: 1 },
+ { key: 0, doc_count: 1 },
+ ],
+ },
+ },
+ })
+ .mockReturnValue({ aggregations: { top_tags: { buckets: [{ key: 24, doc_count: 1 }] } } }),
+ fetchIndices: jest.fn().mockReturnValue([{ index: 'test_index' }]),
+ fetchFields: jest.fn().mockReturnValue({
+ test_index: {
+ mappings: {
+ properties: {
+ str_field: { type: 'string' },
+ bool_field: { type: 'boolean' },
+ num_field: { type: 'integer' },
+ },
+ },
+ },
+ }),
+ } as unknown) as DSLService;
+
+ it('suggests source if empty', async () => {
+ const input = '';
+ const expected = [
+ {
+ label: 'source',
+ input,
+ suggestion: 'source',
+ itemName: 'source',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(dslService.fetchIndices).toBeCalled();
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest source after S', async () => {
+ const input = 'S';
+ const expected = [
+ {
+ label: 'source',
+ input,
+ suggestion: 'ource',
+ itemName: 'source',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+ it('suggests = after source', async () => {
+ const input = 'source ';
+ const expected = [
+ {
+ label: 'source =',
+ input,
+ suggestion: '=',
+ itemName: '=',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests index after source =', async () => {
+ const input = 'source = ';
+ const expected = [
+ {
+ label: 'source = test_index',
+ input,
+ suggestion: 'test_index',
+ itemName: 'test_index',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest index after source = TeSt', async () => {
+ const input = 'source = TeSt';
+ const expected = [
+ {
+ label: 'source = test_index',
+ input,
+ suggestion: '_index',
+ itemName: 'test_index',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests | after source = test_index', async () => {
+ const input = 'source = test_index ';
+ const expected = [
+ {
+ label: 'source = test_index |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ {
+ label: 'source = test_index,',
+ input,
+ suggestion: ',',
+ itemName: ',',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests pipeCommands after |', async () => {
+ const input = 'source = test_index | ';
+ const expected = pipeCommands.map((c) => {
+ return {
+ label: `source = test_index | ${c.label}`,
+ input,
+ suggestion: c.label,
+ itemName: c.label,
+ };
+ }) as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(dslService.fetchFields).toBeCalled();
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest field after where StR_F', async () => {
+ const input = 'source = test_index | where StR_F';
+ const expected = [
+ {
+ label: 'source = test_index | where str_field',
+ input,
+ suggestion: 'ield',
+ itemName: 'str_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests = after where str_field', async () => {
+ const input = 'source = test_index | where str_field ';
+ const expected = [
+ {
+ label: 'source = test_index | where str_field =',
+ input,
+ suggestion: '=',
+ itemName: '=',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(dslService.fetch).toBeCalled();
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests data after where str_field = ', async () => {
+ const input = 'source = test_index | where str_field = ';
+ const expected = [
+ {
+ label: 'source = test_index | where str_field = "data"',
+ input,
+ suggestion: '"data"',
+ itemName: '"data"',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest data after where str_field = "D', async () => {
+ const input = 'source = test_index | where str_field = "D';
+ const expected = [
+ {
+ label: 'source = test_index | where str_field = "data"',
+ input,
+ suggestion: 'ata"',
+ itemName: '"data"',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests | after where str_field = "data"', async () => {
+ const input = 'source = test_index | where str_field = "data" ';
+ const expected = [
+ {
+ label: 'source = test_index | where str_field = "data" |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest field after where BoOl_F', async () => {
+ const input = 'source = test_index | where BoOl_F';
+ const expected = [
+ {
+ label: 'source = test_index | where bool_field',
+ input,
+ suggestion: 'ield',
+ itemName: 'bool_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests = after where bool_field', async () => {
+ const input = 'source = test_index | where bool_field ';
+ const expected = [
+ {
+ label: 'source = test_index | where bool_field =',
+ input,
+ suggestion: '=',
+ itemName: '=',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(dslService.fetch).toBeCalled();
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests data after where bool_field = ', async () => {
+ const input = 'source = test_index | where bool_field = ';
+ const expected = [
+ {
+ label: 'source = test_index | where bool_field = True',
+ input,
+ suggestion: 'True',
+ itemName: 'True',
+ },
+ {
+ label: 'source = test_index | where bool_field = False',
+ input,
+ suggestion: 'False',
+ itemName: 'False',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest data after where bool_field = fA', async () => {
+ const input = 'source = test_index | where bool_field = fA';
+ const expected = [
+ {
+ label: 'source = test_index | where bool_field = False',
+ input,
+ suggestion: 'lse',
+ itemName: 'False',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests | after where bool_field = True', async () => {
+ const input = 'source = test_index | where bool_field = True ';
+ const expected = [
+ {
+ label: 'source = test_index | where bool_field = True |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest match( after where Ma', async () => {
+ const input = 'source = test_index | where Ma';
+ const expected = [
+ {
+ label: 'source = test_index | where match(',
+ input,
+ suggestion: 'tch(',
+ itemName: 'match(',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after where match(', async () => {
+ const input = 'source = test_index | where match( ';
+ const expected = [
+ {
+ label: 'source = test_index | where match( str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | where match( bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | where match( num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests , after where match( num_field', async () => {
+ const input = 'source = test_index | where match( num_field ';
+ const expected = [
+ {
+ label: 'source = test_index | where match( num_field ,',
+ input,
+ suggestion: ',',
+ itemName: ',',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(dslService.fetch).toBeCalled();
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests data after where match( num_field ,', async () => {
+ const input = 'source = test_index | where match( num_field , ';
+ const expected = [
+ {
+ label: 'source = test_index | where match( num_field , 24',
+ input,
+ suggestion: '24',
+ itemName: '24',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests ) after where match( num_field , 24', async () => {
+ const input = 'source = test_index | where match( num_field , 24 ';
+ const expected = [
+ {
+ label: 'source = test_index | where match( num_field , 24 )',
+ input,
+ suggestion: ')',
+ itemName: ')',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests | after where match( num_field , 24 )', async () => {
+ const input = 'source = test_index | where match( num_field , 24 ) ';
+ const expected = [
+ {
+ label: 'source = test_index | where match( num_field , 24 ) |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests statsCommands after stats', async () => {
+ const input = 'source = test_index | stats ';
+ const expected = statsCommands.map((c) => {
+ return {
+ label: `source = test_index | stats ${c.label}`,
+ input,
+ suggestion: c.label,
+ itemName: c.label,
+ };
+ }) as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests by, comma, pipe after stats count()', async () => {
+ const input = 'source = test_index | stats count() ';
+ const expected = [',', '|', 'by'].map((suggestion) => {
+ return {
+ label: `source = test_index | stats count() ${suggestion}`,
+ input,
+ suggestion,
+ itemName: suggestion,
+ };
+ }) as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after stats count() by', async () => {
+ const input = 'source = test_index | stats count() by ';
+ const expected = [
+ {
+ label: 'source = test_index | stats count() by span(',
+ input,
+ suggestion: 'span(',
+ itemName: 'span(',
+ },
+ {
+ label: 'source = test_index | stats count() by str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | stats count() by bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | stats count() by num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests | after stats count() by str_field', async () => {
+ const input = 'source = test_index | stats count() by str_field ';
+ const expected = [
+ {
+ label: 'source = test_index | stats count() by str_field |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests num_field after stats sum(', async () => {
+ const input = 'source = test_index | stats sum( ';
+ const expected = [
+ {
+ label: 'source = test_index | stats sum( num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests by after stats sum( num_field )', async () => {
+ const input = 'source = test_index | stats sum( num_field ) ';
+ const expected = [
+ {
+ label: 'source = test_index | stats sum( num_field ) ,',
+ input,
+ suggestion: ',',
+ itemName: ',',
+ },
+ {
+ label: 'source = test_index | stats sum( num_field ) |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ {
+ label: 'source = test_index | stats sum( num_field ) by',
+ input,
+ suggestion: 'by',
+ itemName: 'by',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after stats sum( num_field ) by', async () => {
+ const input = 'source = test_index | stats sum( num_field ) by ';
+ const expected = [
+ {
+ label: 'source = test_index | stats sum( num_field ) by span(',
+ input,
+ suggestion: 'span(',
+ itemName: 'span(',
+ },
+ {
+ label: 'source = test_index | stats sum( num_field ) by str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | stats sum( num_field ) by bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | stats sum( num_field ) by num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest fields after FiE', async () => {
+ const input = 'source = test_index | FiE';
+ const expected = [
+ {
+ label: 'source = test_index | fields',
+ input,
+ suggestion: 'lds',
+ itemName: 'fields',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after fields', async () => {
+ const input = 'source = test_index | fields ';
+ const expected = [
+ {
+ label: 'source = test_index | fields +',
+ input,
+ suggestion: '+',
+ itemName: '+',
+ },
+ {
+ label: 'source = test_index | fields -',
+ input,
+ suggestion: '-',
+ itemName: '-',
+ },
+ {
+ label: 'source = test_index | fields str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | fields bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | fields num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests , after fields str_field', async () => {
+ const input = 'source = test_index | fields str_field ';
+ const expected = [
+ {
+ label: 'source = test_index | fields str_field ,',
+ input,
+ suggestion: ',',
+ itemName: ',',
+ },
+ {
+ label: 'source = test_index | fields str_field |',
+ input,
+ suggestion: '|',
+ itemName: '|',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after fields str_field, ', async () => {
+ const input = 'source = test_index | fields str_field , ';
+ const expected = [
+ {
+ label: 'source = test_index | fields str_field , str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | fields str_field , bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | fields str_field , num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('continues to suggest dedup after DE', async () => {
+ const input = 'source = test_index | DE';
+ const expected = [
+ {
+ label: 'source = test_index | dedup',
+ input,
+ suggestion: 'dup',
+ itemName: 'dedup',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+
+ it('suggests fields after dedup', async () => {
+ const input = 'source = test_index | dedup ';
+ const expected = [
+ {
+ label: 'source = test_index | dedup str_field',
+ input,
+ suggestion: 'str_field',
+ itemName: 'str_field',
+ },
+ {
+ label: 'source = test_index | dedup bool_field',
+ input,
+ suggestion: 'bool_field',
+ itemName: 'bool_field',
+ },
+ {
+ label: 'source = test_index | dedup num_field',
+ input,
+ suggestion: 'num_field',
+ itemName: 'num_field',
+ },
+ ] as AutocompleteItem[];
+ const suggestion = await parseGetSuggestions('', input, dslService);
+ expect(suggestion).toStrictEqual(expected);
+ });
+});
diff --git a/dashboards-observability/public/components/common/search/autocomplete.tsx b/dashboards-observability/public/components/common/search/autocomplete.tsx
new file mode 100644
index 000000000..3d3fdac26
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/autocomplete.tsx
@@ -0,0 +1,215 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import './search.scss';
+import $ from 'jquery';
+import React, { useEffect, useMemo, useState } from 'react';
+import { AutocompleteState, createAutocomplete } from '@algolia/autocomplete-core';
+import { EuiFieldText, EuiTextArea } from '@elastic/eui';
+import DSLService from 'public/services/requests/dsl';
+import { IQueryBarProps } from './search';
+import { uiSettingsService } from '../../../../common/utils';
+import { AutocompleteItem } from '../../../../common/constants/autocomplete';
+
+interface AutocompleteProps extends IQueryBarProps {
+ getSuggestions: (
+ base: string,
+ query: string,
+ dslService: DSLService,
+ possibleCommands: Array<{ label: string }>
+ ) => Promise;
+ onItemSelect: any;
+ isDisabled?: boolean;
+ baseQuery: string;
+ tabId: string;
+ placeholder?: string;
+ possibleCommands?: Array<{ label: string }>;
+ append?: any;
+}
+
+export const Autocomplete = (props: AutocompleteProps) => {
+ const {
+ query,
+ tempQuery,
+ handleQueryChange,
+ handleQuerySearch,
+ dslService,
+ getSuggestions,
+ onItemSelect,
+ isDisabled,
+ baseQuery,
+ tabId = '',
+ placeholder = 'Enter PPL query',
+ possibleCommands,
+ append,
+ } = props;
+
+ const [autocompleteState, setAutocompleteState] = useState>({
+ collections: [],
+ completion: null,
+ context: {},
+ isOpen: false,
+ query: tempQuery,
+ activeItemId: null,
+ status: 'idle',
+ });
+
+ const appLogEvents = tabId.startsWith('application-analytics-tab');
+ const panelsFilter = tabId === 'panels-filter';
+
+ useEffect(() => {
+ const searchBar = document.getElementById('autocomplete-textarea');
+
+ searchBar?.addEventListener('keydown', (e) => {
+ const keyCode = e.which || e.keyCode;
+ if (keyCode === 13 && e.shiftKey) {
+ handleQuerySearch();
+ }
+ return () => {
+ $('#autocomplete-textarea').unbind('keydown');
+ };
+ });
+ }, []);
+
+ const depArray =
+ appLogEvents || panelsFilter
+ ? [baseQuery, query, dslService, autocompleteState]
+ : [baseQuery, query, dslService];
+
+ const autocomplete = useMemo(() => {
+ return createAutocomplete<
+ AutocompleteItem,
+ React.BaseSyntheticEvent,
+ React.MouseEvent,
+ React.KeyboardEvent
+ >({
+ openOnFocus: true,
+ defaultActiveItemId: 0,
+ onStateChange: ({ state }) => {
+ setAutocompleteState({
+ ...state,
+ });
+ handleQueryChange(state.query);
+ },
+ initialState: {
+ ...autocompleteState,
+ query: query || '',
+ },
+ getSources() {
+ return [
+ {
+ sourceId: 'querySuggestions',
+ // eslint-disable-next-line no-shadow
+ async getItems({ query }) {
+ const suggestions = await getSuggestions(
+ baseQuery,
+ query,
+ dslService,
+ possibleCommands
+ );
+ return suggestions;
+ },
+ onSelect: ({ setQuery, item }) => {
+ onItemSelect(
+ {
+ setQuery,
+ item,
+ },
+ dslService
+ );
+ $('#autocomplete-textarea').blur();
+ $('#autocomplete-textarea').focus();
+ },
+ },
+ ];
+ },
+ });
+ }, depArray);
+
+ const TextArea = panelsFilter ? EuiFieldText : EuiTextArea;
+
+ return (
+
+
+ {autocompleteState.isOpen && (
+
+ {autocompleteState.collections.map((collection, index) => {
+ const { source, items } = collection;
+ const filteredItems = items.filter((item, itemIndex) => {
+ return items.findIndex((i) => i.itemName === item.itemName) === itemIndex;
+ });
+ return (
+
+
+ {items.length > 0 && (
+
+ {filteredItems.map((item) => {
+ const fullWord = item.itemName;
+ return (
+
+
+
+
+
+ ${fullWord.slice(0, -item.suggestion.length)} ${
+ item.suggestion
+ }
+
`,
+ }}
+ />
+
+
+
+
+ );
+ })}
+
+ )}
+
+
+ );
+ })}
+
+ )}
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/search/autocomplete_logic.ts b/dashboards-observability/public/components/common/search/autocomplete_logic.ts
new file mode 100644
index 000000000..347d0e3b3
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/autocomplete_logic.ts
@@ -0,0 +1,378 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import DSLService from 'public/services/requests/dsl';
+import { isEmpty } from 'lodash';
+import { getDataValueQuery } from './queries/data_queries';
+import {
+ statsCommands,
+ numberTypes,
+ pipeCommands,
+ DataItem,
+ FieldItem,
+ IndexItem,
+ AutocompleteItem,
+ regexForIndex,
+ regexForSuggestion,
+ PIPE_AFTER_WHERE,
+ DATA_AFTER_WHERE_EQUAL,
+ EMPTY_REGEX,
+ EQUAL_AFTER_WHERE_FIELD,
+ MATCH_FIELD_AFTER_WHERE,
+ COMMA_AFTER_FIELD,
+ DATA_AFTER_COMMA,
+ CLOSE_AFTER_DATA,
+ PIPE_AFTER_MATCH,
+ FIELD_IN_FIELD_LOOP,
+ COMMA_PIPE_AFTER_FIELD,
+ PIPE_AFTER_KEEP_EMPTY,
+ PIPE_AFTER_CONSECUTIVE,
+ EQUAL_AFTER_EVAL_FIELD,
+ FIELD_AFTER_EVAL_EQUAL,
+ MATH_AFTER_FIELD,
+ PIPE_MATH_AFTER_EXPRESSIONS,
+ PLUS_MINUS_FIELD_AFTER_FIELDS,
+ FIELD_AFTER_PLUS_MINUS,
+ COMMA_PIPE_AFTER_FIELDS,
+ FIELD_IN_FIELDS_LOOP,
+ RARE_TOP_FIELD_LOOP,
+ COMMA_PIPE_BY_AFTER_FIELD,
+ FIELD_AFTER_BY,
+ PIPE_AFTER_GROUP_BY,
+ AS_AFTER_FIELD,
+ COMMA_PIPE_AFTER_RENAME_FIELD,
+ FIELD_AFTER_COMMA,
+ PIPE_AFTER_HEAD,
+ PLUS_MINUS_FIELD_AFTER_SORT,
+ FIELD_AFTER_PLUS_MINUS_SORT,
+ COMMA_PIPE_AFTER_SORT_FIELD,
+ PLUS_MINUS_FIELD_IN_FIELDS_LOOP,
+ FIELD_AFTER_COMMAND,
+ FIELD_SPAN_AFTER_GROUP_BY,
+ NUM_FIELD_AFTER_AGGREGATION,
+ CLOSE_AFTER_FIELD,
+ COMMA_PIPE_BY_AFTER_AGGREGATION,
+ PIPE_AFTER_STATS_GROUP_BY,
+ AGGREGATION_FOR_STATS,
+ FIELD_AFTER_SPAN,
+ CLOSE_AFTER_SPAN,
+ PIPE_AFTER_SPAN,
+ STRING_FIELD_AFTER_PARSE,
+ PIPE_AFTER_PARSE,
+ EQUAL_AFTER_SOURCE,
+ INDEX_AFTER_EQUAL,
+ PIPE_COMMA_AFTER_INDEX,
+ MORE_INDEX_AFTER_COMMA,
+} from '../../../../common/constants/autocomplete';
+
+let currIndices: string[] = [];
+let currField: string = '';
+let currFieldType: string = '';
+
+const indexList: string[] = [];
+const fieldList: string[] = [];
+const fieldsFromBackend: FieldItem[] = [];
+const indicesFromBackend: IndexItem[] = [];
+const dataValuesFromBackend: DataItem[] = [];
+
+const getIndices = async (dslService: DSLService): Promise => {
+ if (indicesFromBackend.length === 0) {
+ const indices = (await dslService.fetchIndices()).filter(
+ ({ index }: { index: any }) => !index.startsWith('.')
+ );
+ for (let i = 0; i < indices.length; i++) {
+ indicesFromBackend.push({
+ label: indices[i].index,
+ });
+ indexList.push(indices[i].index);
+ }
+ }
+};
+
+const getFields = async (dslService: DSLService): Promise => {
+ if (!isEmpty(currIndices)) {
+ fieldsFromBackend.length = 0;
+ for (let i = 0; i < currIndices.length; i++) {
+ const index = currIndices[i];
+ const res = await dslService.fetchFields(index);
+ if (!res) {
+ return;
+ }
+ const resFieldList = Object.keys(res?.[index].mappings.properties);
+ for (let j = 0; j < resFieldList.length; j++) {
+ const element = resFieldList[j];
+ if (
+ res?.[index].mappings.properties[element].properties ||
+ res?.[index].mappings.properties[element].fields
+ ) {
+ fieldsFromBackend.push({ label: element, type: 'string' });
+ } else if (res?.[index].mappings.properties[element].type === 'keyword') {
+ fieldsFromBackend.push({ label: element, type: 'string' });
+ } else {
+ fieldsFromBackend.push({
+ label: element,
+ type: res?.[index].mappings.properties[element].type,
+ });
+ }
+ fieldList.push(element);
+ }
+ }
+ }
+};
+
+const getDataValues = async (
+ indices: string[],
+ field: string,
+ fieldType: string,
+ dslService: DSLService
+): Promise => {
+ for (let i = 0; i < indices.length; i++) {
+ const index = indices[i];
+ const res = (await dslService.fetch(getDataValueQuery(index, field)))?.aggregations?.top_tags
+ ?.buckets;
+ if (isEmpty(res)) {
+ continue;
+ }
+ dataValuesFromBackend.length = 0;
+ res.forEach((e: any) => {
+ if (fieldType === 'string') {
+ dataValuesFromBackend.push({ label: '"' + e.key + '"', doc_count: e.doc_count });
+ } else if (fieldType === 'boolean') {
+ if (e.key === 1) {
+ dataValuesFromBackend.push({ label: 'True', doc_count: e.doc_count });
+ } else {
+ dataValuesFromBackend.push({ label: 'False', doc_count: e.doc_count });
+ }
+ } else if (fieldType !== 'geo_point') {
+ dataValuesFromBackend.push({ label: String(e.key), doc_count: e.doc_count });
+ }
+ });
+ return dataValuesFromBackend;
+ }
+ return [];
+};
+
+export const onItemSelect = async (
+ { setQuery, item }: { setQuery: any; item: any },
+ dslService: DSLService
+) => {
+ if (fieldsFromBackend.length === 0 && indexList.includes(item.itemName)) {
+ currIndices = [item.itemName];
+ getFields(dslService);
+ }
+ setQuery(item.label + ' ');
+};
+
+// Function to create the array of objects to be suggested
+const fillSuggestions = (str: string, word: string, items: any): AutocompleteItem[] => {
+ const lowerWord = word.toLowerCase();
+ const suggestionList = [];
+ for (let i = 0; i < items.length; i++) {
+ suggestionList.push({
+ label: str.substring(0, str.lastIndexOf(word)) + items[i].label,
+ input: str,
+ suggestion: items[i].label.substring(word.length),
+ itemName: items[i].label,
+ });
+ }
+ return filterSuggestions(suggestionList, lowerWord);
+};
+
+// Function to filter out currently inputed suggestions
+const filterSuggestions = (suggestions: AutocompleteItem[], prefix: string) => {
+ return suggestions.filter(
+ ({ itemName }) =>
+ itemName.toLowerCase().startsWith(prefix) && prefix.localeCompare(itemName.toLowerCase())
+ );
+};
+
+export const parseForIndices = (query: string) => {
+ for (let i = 0; i < regexForIndex.length; i++) {
+ const groupArray = regexForIndex[i].exec(query);
+ if (groupArray) {
+ const afterEqual = query.substring(query.indexOf('=') + 1);
+ const noSpaces = afterEqual.replace(/\s/g, '');
+ return noSpaces.split(',');
+ }
+ }
+ return [];
+};
+
+const parseForNextSuggestion = (command: string) => {
+ for (let i = 0; i < regexForSuggestion.length; i++) {
+ const groupArray = regexForSuggestion[i].exec(command);
+ if (groupArray) {
+ return regexForSuggestion[i];
+ }
+ }
+};
+
+export const parseGetSuggestions = async (
+ base: string,
+ currQuery: string,
+ dslService: DSLService,
+ possibleCommands: Array<{ label: string }> = pipeCommands
+) => {
+ const fullQuery = base ? base + '| ' + currQuery : currQuery;
+ const splitSpaceQuery = fullQuery.split(' ');
+ const splitPipeQuery = fullQuery.split('|');
+
+ const lastWord = splitSpaceQuery[splitSpaceQuery.length - 1];
+ const lastCommand = splitPipeQuery[splitPipeQuery.length - 1];
+ const firstCommand = splitPipeQuery[0];
+
+ if (!base && isEmpty(indicesFromBackend)) {
+ await getIndices(dslService);
+ }
+
+ if (fullQuery.match(EMPTY_REGEX)) {
+ return fillSuggestions(currQuery, lastWord, [{ label: 'source' }]);
+ }
+
+ const next = parseForNextSuggestion(lastCommand);
+ if (next) {
+ switch (next) {
+ case AGGREGATION_FOR_STATS:
+ return fillSuggestions(currQuery, lastWord, statsCommands);
+ case AS_AFTER_FIELD:
+ return fillSuggestions(currQuery, lastWord, [{ label: 'as' }]);
+ case COMMA_PIPE_BY_AFTER_FIELD:
+ case COMMA_PIPE_BY_AFTER_AGGREGATION:
+ return fillSuggestions(currQuery, lastWord, [
+ { label: ',' },
+ { label: '|' },
+ { label: 'by' },
+ ]);
+ case COMMA_PIPE_AFTER_FIELDS:
+ case COMMA_PIPE_AFTER_RENAME_FIELD:
+ case COMMA_PIPE_AFTER_SORT_FIELD:
+ return fillSuggestions(currQuery, lastWord, [{ label: ',' }, { label: '|' }]);
+ case PIPE_COMMA_AFTER_INDEX:
+ return filterSuggestions(
+ [
+ { label: currQuery + '|', input: currQuery, suggestion: '|', itemName: '|' },
+ { label: currQuery.trim() + ',', input: currQuery, suggestion: ',', itemName: ',' },
+ ],
+ lastWord
+ );
+ case PLUS_MINUS_FIELD_AFTER_FIELDS:
+ case PLUS_MINUS_FIELD_AFTER_SORT:
+ case PLUS_MINUS_FIELD_IN_FIELDS_LOOP:
+ return fillSuggestions(currQuery, lastWord, [
+ { label: '+' },
+ { label: '-' },
+ ...fieldsFromBackend,
+ ]);
+ case PIPE_MATH_AFTER_EXPRESSIONS:
+ return fillSuggestions(currQuery, lastWord, [
+ { label: '|' },
+ { label: '+' },
+ { label: '-' },
+ { label: '*' },
+ { label: '/' },
+ ]);
+ case MATH_AFTER_FIELD:
+ return fillSuggestions(currQuery, lastWord, [
+ { label: '+' },
+ { label: '-' },
+ { label: '*' },
+ { label: '/' },
+ ]);
+ case COMMA_PIPE_AFTER_FIELD:
+ return fillSuggestions(currQuery, lastWord, [
+ { label: ',' },
+ { label: '|' },
+ { label: 'keepempty=true' },
+ { label: 'consecutive=true' },
+ ]);
+ case CLOSE_AFTER_DATA:
+ case CLOSE_AFTER_FIELD:
+ case CLOSE_AFTER_SPAN:
+ return fillSuggestions(currQuery, lastWord, [{ label: ')' }]);
+ case COMMA_AFTER_FIELD:
+ currField = COMMA_AFTER_FIELD.exec(lastCommand)![1];
+ currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || '';
+ await getDataValues(currIndices, currField, currFieldType, dslService);
+ return fillSuggestions(currQuery, lastWord, [{ label: ',' }]);
+ case FIELD_AFTER_SPAN:
+ const matchArray = FIELD_AFTER_SPAN.exec(lastCommand);
+ const tempField = matchArray![matchArray!.length - 1];
+ if (fieldList.includes(tempField)) {
+ currField = tempField;
+ currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || '';
+ await getDataValues(currIndices, currField, currFieldType, dslService);
+ return fillSuggestions(currQuery, lastWord, [{ label: ',' }]);
+ } else {
+ return fillSuggestions(currQuery, lastWord, fieldsFromBackend);
+ }
+ case FIELD_AFTER_COMMAND:
+ case FIELD_IN_FIELD_LOOP:
+ case FIELD_AFTER_EVAL_EQUAL:
+ case FIELD_AFTER_PLUS_MINUS:
+ case FIELD_IN_FIELDS_LOOP:
+ case RARE_TOP_FIELD_LOOP:
+ case FIELD_AFTER_BY:
+ case FIELD_AFTER_COMMA:
+ case FIELD_AFTER_PLUS_MINUS_SORT:
+ return fillSuggestions(currQuery, lastWord, fieldsFromBackend);
+ case FIELD_SPAN_AFTER_GROUP_BY:
+ return fillSuggestions(currQuery, lastWord, [{ label: 'span(' }, ...fieldsFromBackend]);
+ case NUM_FIELD_AFTER_AGGREGATION:
+ const numberFields = fieldsFromBackend.filter((field: { type: string }) =>
+ numberTypes.includes(field.type)
+ );
+ return fillSuggestions(currQuery, lastWord, numberFields);
+ case STRING_FIELD_AFTER_PARSE:
+ return fillSuggestions(
+ currQuery,
+ lastWord,
+ fieldsFromBackend.filter((field) => field.type === 'string')
+ );
+ case PIPE_AFTER_WHERE:
+ case PIPE_AFTER_MATCH:
+ case PIPE_AFTER_KEEP_EMPTY:
+ case PIPE_AFTER_CONSECUTIVE:
+ case PIPE_AFTER_GROUP_BY:
+ case PIPE_AFTER_HEAD:
+ case PIPE_AFTER_STATS_GROUP_BY:
+ case PIPE_AFTER_SPAN:
+ case PIPE_AFTER_PARSE:
+ return fillSuggestions(currQuery, lastWord, [{ label: '|' }]);
+ case DATA_AFTER_WHERE_EQUAL:
+ case DATA_AFTER_COMMA:
+ return fillSuggestions(currQuery, lastWord, dataValuesFromBackend);
+ case EQUAL_AFTER_WHERE_FIELD:
+ case EQUAL_AFTER_EVAL_FIELD:
+ currField = next.exec(lastCommand)![1];
+ currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || '';
+ await getDataValues(currIndices, currField, currFieldType, dslService);
+ return fillSuggestions(currQuery, lastWord, [{ label: '=' }]);
+ case MATCH_FIELD_AFTER_WHERE:
+ return fillSuggestions(currQuery, lastWord, [{ label: 'match(' }, ...fieldsFromBackend]);
+ case EQUAL_AFTER_SOURCE:
+ return fillSuggestions(currQuery, lastWord, [{ label: '=' }]);
+ case INDEX_AFTER_EQUAL:
+ return fillSuggestions(currQuery, lastWord, indicesFromBackend);
+ case MORE_INDEX_AFTER_COMMA:
+ const trimmedIndices = indicesFromBackend.map((index) => {
+ return {
+ label: currQuery.substring(0, currQuery.lastIndexOf(lastWord)).trim() + index.label,
+ input: currQuery,
+ suggestion: index.label.substring(lastWord.length),
+ itemName: index.label,
+ };
+ });
+ return filterSuggestions(trimmedIndices, lastWord);
+ case EMPTY_REGEX:
+ currIndices = parseForIndices(firstCommand);
+ await getFields(dslService);
+ currField = '';
+ currFieldType = '';
+ return fillSuggestions(currQuery, lastWord, possibleCommands);
+ }
+ }
+
+ return [];
+};
diff --git a/dashboards-observability/public/components/common/search/date_picker.tsx b/dashboards-observability/public/components/common/search/date_picker.tsx
new file mode 100644
index 000000000..75087c9f1
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/date_picker.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiSuperDatePicker } from '@elastic/eui';
+import { IDatePickerProps } from './search';
+import { uiSettingsService } from '../../../../common/utils';
+
+export function DatePicker(props: IDatePickerProps) {
+ const { startTime, endTime, handleTimePickerChange, handleTimeRangePickerRefresh } = props;
+
+ const handleTimeChange = (e: any) => handleTimePickerChange([e.start, e.end]);
+
+ return (
+
+ );
+}
diff --git a/dashboards-observability/public/components/common/search/queries/data_queries.ts b/dashboards-observability/public/components/common/search/queries/data_queries.ts
new file mode 100644
index 000000000..69ee9dcf2
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/queries/data_queries.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const getDataValueQuery = (index: string, field: string) => {
+ const query = {
+ index: index,
+ 'size': 0,
+ 'aggs': {
+ 'top_tags': {
+ 'terms': {
+ 'field': field,
+ }
+ }
+ }
+ }
+ return query;
+}
diff --git a/dashboards-observability/public/components/common/search/request_handler.tsx b/dashboards-observability/public/components/common/search/request_handler.tsx
new file mode 100644
index 000000000..e263f39dc
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/request_handler.tsx
@@ -0,0 +1,17 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import _ from 'lodash';
+import { CoreStart } from '../../../../../../src/core/public';
+
+const DSL_ROUTE = '/api/dsl/search';
+
+export function handleDslRequest(http: CoreStart['http'], query) {
+ return http
+ .post(DSL_ROUTE, {
+ body: JSON.stringify(query),
+ })
+ .catch((error) => console.error(error));
+}
diff --git a/dashboards-observability/public/components/common/search/search.scss b/dashboards-observability/public/components/common/search/search.scss
new file mode 100644
index 000000000..1b0666a6d
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/search.scss
@@ -0,0 +1,79 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.globalQueryBar {
+ margin: .5rem 0;
+ padding: .5rem;
+}
+.aa-Autocomplete {
+ width: 100%;
+ position: relative;
+ margin: 4px;
+ margin-left: 8px;
+ --aa-search-input-height: 38px;
+ --aa-panel-border-color-rgb: rgba(227,230,238,255);
+ --aa-input-background-color-rbg: rgba(250,251,253,255);
+}
+.styling {
+ font-weight: bold;
+}
+
+#servicesEntities {
+ position: relative;
+ z-index: 0;
+}
+
+#autocomplete-textarea {
+ width: 100%;
+ outline: none;
+ min-height: 48px;
+ max-width: unset;
+ height: 45px;
+ resize: vertical;
+ font-size: 16px;
+ padding-right: 40px;
+}
+
+.aa-Panel {
+ width: 100%;
+ z-index: 2500;
+}
+
+.aa-Panel--scrollable-dark {
+ background-color: #1D1E24;
+ border: 2px groove #383444;
+}
+
+.aa-Item-dark {
+ color: #DFE5EF;
+}
+
+.event-date-picker {
+ max-width: 35vw;
+}
+
+.ppl-link {
+ border: unset;
+ position: absolute;
+ top: 14px;
+ right: 15px;
+ background-color: transparent;
+}
+.ppl-link-light {
+ color: #006BB4;
+}
+
+.ppl-link-dark {
+ color: #1BA9F5;
+}
+
+.base-query-popover {
+ border: unset;
+ font-size: 17px;
+ position: absolute;
+ top: 20px;
+ left: 8px;
+ background-color: transparent;
+}
diff --git a/dashboards-observability/public/components/common/search/search.test.tsx b/dashboards-observability/public/components/common/search/search.test.tsx
new file mode 100644
index 000000000..6a7543fec
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/search.test.tsx
@@ -0,0 +1,71 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import React from 'react';
+import { Search } from './search';
+
+describe('Search bar', () => {
+ it('handles query change', () => {
+ const query = 'rawQuery';
+ const tempQuery = 'rawQuery';
+ const handleQueryChange = jest.fn();
+ const handleQuerySearch = jest.fn();
+ const dslService = jest.fn();
+ const handleTimePickerChange = jest.fn();
+ const selectedPanelName = jest.fn();
+ const selectedCustomPanelOptions = jest.fn();
+ const setSelectedPanelName = jest.fn();
+ const setSelectedCustomPanelOptions = jest.fn();
+ const handleSavingObject = jest.fn();
+ const isPanelTextFieldInvalid = jest.fn();
+ const showSavePanelOptionsList = jest.fn();
+ const handleTimeRangePickerRefresh = jest.fn();
+ const savedObjects = jest.fn();
+ const getFullSuggestions = jest.fn();
+ const onItemSelect = jest.fn();
+ const dateRange = ['now-15m', 'now'];
+ const liveTailButton = jest.fn();
+ const isLiveTailPopoverOpen = jest.fn();
+ const closeLiveTailPopover = jest.fn();
+ const popoverItems = jest.fn();
+ const isLiveTailOn = jest.fn();
+ const countDistribution = jest.fn();
+ const utils = render(
+
+ );
+
+ const searchBar = utils.getByPlaceholderText('Enter PPL query');
+ fireEvent.change(searchBar, { target: { value: 'new query' } });
+ expect(handleQueryChange).toBeCalledWith('new query');
+ });
+});
diff --git a/dashboards-observability/public/components/common/search/search.tsx b/dashboards-observability/public/components/common/search/search.tsx
new file mode 100644
index 000000000..af9a21f89
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/search.tsx
@@ -0,0 +1,253 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './search.scss';
+
+import React, { useState } from 'react';
+import {
+ EuiFlexGroup,
+ EuiButton,
+ EuiFlexItem,
+ EuiPopover,
+ EuiButtonEmpty,
+ EuiPopoverFooter,
+ EuiBadge,
+ EuiContextMenuPanel,
+ EuiToolTip,
+} from '@elastic/eui';
+import _ from 'lodash';
+import { DatePicker } from './date_picker';
+import '@algolia/autocomplete-theme-classic';
+import { Autocomplete } from './autocomplete';
+import { SavePanel } from '../../explorer/save_panel';
+import { PPLReferenceFlyout } from '../helpers';
+import { uiSettingsService } from '../../../../common/utils';
+import { APP_ANALYTICS_TAB_ID_REGEX } from '../../../../common/constants/explorer';
+import { LiveTailButton, StopLiveButton } from '../live_tail/live_tail_button';
+export interface IQueryBarProps {
+ query: string;
+ tempQuery: string;
+ handleQueryChange: (query: string) => void;
+ handleQuerySearch: () => void;
+ dslService: any;
+}
+
+export interface IDatePickerProps {
+ startTime: string;
+ endTime: string;
+ setStartTime: () => void;
+ setEndTime: () => void;
+ setTimeRange: () => void;
+ setIsOutputStale: () => void;
+ handleTimePickerChange: (timeRange: string[]) => any;
+ handleTimeRangePickerRefresh: () => any;
+}
+
+export const Search = (props: any) => {
+ const {
+ query,
+ tempQuery,
+ handleQueryChange,
+ handleQuerySearch,
+ handleTimePickerChange,
+ dslService,
+ startTime,
+ endTime,
+ setStartTime,
+ setEndTime,
+ setIsOutputStale,
+ selectedPanelName,
+ selectedCustomPanelOptions,
+ setSelectedPanelName,
+ setSelectedCustomPanelOptions,
+ handleSavingObject,
+ isPanelTextFieldInvalid,
+ savedObjects,
+ showSavePanelOptionsList,
+ showSaveButton = true,
+ handleTimeRangePickerRefresh,
+ liveTailButton,
+ isLiveTailPopoverOpen,
+ closeLiveTailPopover,
+ popoverItems,
+ isLiveTailOn,
+ selectedSubTabId,
+ searchBarConfigs = {},
+ getSuggestions,
+ onItemSelect,
+ tabId = '',
+ baseQuery = '',
+ stopLive,
+ setIsLiveTailPopoverOpen,
+ liveTailName,
+ } = props;
+
+ const appLogEvents = tabId.match(APP_ANALYTICS_TAB_ID_REGEX);
+
+ const [isSavePanelOpen, setIsSavePanelOpen] = useState(false);
+ const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
+
+ const closeFlyout = () => {
+ setIsFlyoutVisible(false);
+ };
+
+ const showFlyout = () => {
+ setIsFlyoutVisible(true);
+ };
+
+ let flyout;
+ if (isFlyoutVisible) {
+ flyout = ;
+ }
+
+ const Savebutton = (
+ {
+ setIsSavePanelOpen((staleState) => {
+ return !staleState;
+ });
+ }}
+ data-test-subj="eventExplorer__saveManagementPopover"
+ iconType="arrowDown"
+ >
+ Save
+
+ );
+
+ const liveButton = (
+
+ );
+
+ return (
+
+
+ {appLogEvents && (
+
+
+
+ Base Query
+
+
+
+ )}
+
+
+ showFlyout()}
+ onClickAriaLabel={'pplLinkShowFlyout'}
+ >
+ PPL
+
+
+
+
+ {!isLiveTailOn && (
+ handleTimePickerChange(timeRange)}
+ handleTimeRangePickerRefresh={handleTimeRangePickerRefresh}
+ />
+ )}
+
+ {showSaveButton && !showSavePanelOptionsList && (
+
+
+
+
+
+ )}
+ {isLiveTailOn && (
+
+
+
+ )}
+ {showSaveButton && searchBarConfigs[selectedSubTabId]?.showSaveButton && (
+ <>
+
+ setIsSavePanelOpen(false)}
+ >
+
+
+
+
+ setIsSavePanelOpen(false)}
+ data-test-subj="eventExplorer__querySaveCancel"
+ >
+ Cancel
+
+
+
+ {
+ handleSavingObject();
+ setIsSavePanelOpen(false);
+ }}
+ data-test-subj="eventExplorer__querySaveConfirm"
+ >
+ Save
+
+
+
+
+
+
+ >
+ )}
+
+ {flyout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/common/search/searchindex.tsx b/dashboards-observability/public/components/common/search/searchindex.tsx
new file mode 100644
index 000000000..0a7fe4460
--- /dev/null
+++ b/dashboards-observability/public/components/common/search/searchindex.tsx
@@ -0,0 +1,60 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiComboBox } from '@elastic/eui';
+import React, { useState, useEffect, memo } from 'react';
+
+
+export const IndexPicker = memo(function indexDropdown(props: any) {
+ return ;
+});
+
+interface Fetch {
+ dslService: any;
+ query: any;
+ handleQueryChange: (query: string, index: string) => void;
+}
+
+export function SearchIndex(options: Fetch) {
+
+ const [indicesFromBackend, setindicesFromBackend] = useState([]);
+
+ // fetch indices from backend
+ const getIndices = async (dslService: any) => {
+ if (indicesFromBackend.length === 0) {
+ const indices = (await dslService.fetchIndices()).filter(
+ ({ index }) => !index.startsWith('.')
+ );
+ for (let i = 0; i < indices.length; i++) {
+ indicesFromBackend.push({
+ label: indices[i].index,
+ });
+ }
+ }
+ };
+
+ useEffect(() => {
+ getIndices(options.dslService);
+ }, []);
+
+ const [selectedOptions, setSelected] = useState(
+ []
+ );
+
+ // handle Index Change
+ const onChange = (selectedOptions) => {
+ options.handleQueryChange(options.query, selectedOptions);
+ setSelected(selectedOptions);
+ };
+
+ return (
+ onChange(e)}
+ />
+ );
+}
diff --git a/dashboards-observability/public/components/common/side_nav.tsx b/dashboards-observability/public/components/common/side_nav.tsx
new file mode 100644
index 000000000..0f63ed243
--- /dev/null
+++ b/dashboards-observability/public/components/common/side_nav.tsx
@@ -0,0 +1,140 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPage,
+ EuiPageBody,
+ EuiPageSideBar,
+ EuiSideNav,
+ EuiSideNavItemType,
+ EuiSwitch,
+} from '@elastic/eui';
+import React from 'react';
+import { useState } from 'react';
+import { toMountPoint } from '../../../../../src/plugins/opensearch_dashboards_react/public';
+import { uiSettingsService } from '../../../common/utils';
+
+export function ObservabilitySideBar(props: { children: React.ReactNode }) {
+ // set items.isSelected based on location.hash passed in
+ // tries to find an item where href is a prefix of the hash
+ // if none will try to find an item where the hash is a prefix of href
+ function setIsSelected(
+ items: EuiSideNavItemType[],
+ hash: string,
+ initial = true,
+ reverse = false
+ ): boolean {
+ // Default page is Events Analytics
+ // But it is kept as second option in side nav
+ if (hash === '#/') {
+ items[0].items[2].isSelected = true;
+ return true;
+ }
+ for (let i = 0; i < items.length; i++) {
+ const item = items[i];
+ if (item.href && ((reverse && item.href.startsWith(hash)) || hash.startsWith(item.href))) {
+ item.isSelected = true;
+ return true;
+ }
+ if (item.items?.length && setIsSelected(item.items, hash, false, reverse)) return true;
+ }
+ return initial && setIsSelected(items, hash, false, !reverse);
+ }
+
+ const items = [
+ {
+ name: 'Observability',
+ id: 0,
+ items: [
+ {
+ name: 'Application analytics',
+ id: 1,
+ href: '#/application_analytics',
+ },
+ {
+ name: 'Trace analytics',
+ id: 2,
+ href: '#/trace_analytics/home',
+ items: [
+ {
+ name: 'Traces',
+ id: 2.1,
+ href: '#/trace_analytics/traces',
+ },
+ {
+ name: 'Services',
+ id: 2.2,
+ href: '#/trace_analytics/services',
+ },
+ ],
+ },
+ {
+ name: 'Event analytics',
+ id: 3,
+ href: '#/event_analytics',
+ },
+ {
+ name: 'Operational panels',
+ id: 4,
+ href: '#/operational_panels/',
+ },
+ {
+ name: 'Notebooks',
+ id: 5,
+ href: '#/notebooks',
+ },
+ ],
+ },
+ ];
+ setIsSelected(items, location.hash);
+ const [isDarkMode, setIsDarkMode] = useState(uiSettingsService.get('theme:darkMode'));
+
+ return (
+
+
+
+
+
+
+
+ {
+ uiSettingsService.set('theme:darkMode', !isDarkMode).then((resp) => {
+ setIsDarkMode(!isDarkMode);
+ uiSettingsService.addToast({
+ title: 'Theme setting changes require you to reload the page to take effect.',
+ text: toMountPoint(
+ <>
+
+
+ window.location.reload()}>
+ Reload page
+
+
+
+ >
+ ),
+ color: 'success',
+ });
+ });
+ }}
+ />
+
+
+
+ {props.children}
+
+ );
+}
diff --git a/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_table.test.tsx.snap b/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_table.test.tsx.snap
new file mode 100644
index 000000000..29687e509
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_table.test.tsx.snap
@@ -0,0 +1,2894 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Panels Table Component renders empty panel table container 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ Operational panels
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Panels
+
+ (
+ 0
+ )
+
+
+
+
+
+
+
+
+
+
+ Use Operational panels to create and view different visualizations on ingested observability data, using PPL (Piped Processing Language) queries.
+
+
+
+ Learn more
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No Operational Panels
+
+
+
+
+
+
+
+
+ Use operational panels to dive deeper into observability
+
+ using PPL queries and insightful visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add samples
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Panels Table Component renders panel table container 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ Operational panels
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Panels
+
+ (
+ 4
+ )
+
+
+
+
+
+
+
+
+
+
+ Use Operational panels to create and view different visualizations on ingested observability data, using PPL (Piped Processing Language) queries.
+
+
+
+ Learn more
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select all rows
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sorting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+ Click to sort in ascending order
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Last updated
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to sort in ascending order
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created
+
+
+
+
+
+
+ Click to sort in ascending order
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Last updated
+
+
+ 11/04/2021 06:10 PM
+
+
+
+
+
+
+ Created
+
+
+ 11/02/2021 07:26 PM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Last updated
+
+
+ 11/03/2021 10:51 PM
+
+
+
+
+
+
+ Created
+
+
+ 11/02/2021 09:44 PM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Last updated
+
+
+ 11/03/2021 10:37 PM
+
+
+
+
+
+
+ Created
+
+
+ 10/29/2021 10:15 PM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+ Last updated
+
+
+ 11/03/2021 09:26 PM
+
+
+
+
+
+
+ Created
+
+
+ 11/03/2021 09:26 PM
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+ 10
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rows per page
+
+ :
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_view.test.tsx.snap b/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_view.test.tsx.snap
new file mode 100644
index 000000000..2c020c56b
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/__tests__/__snapshots__/custom_panel_view.test.tsx.snap
@@ -0,0 +1,5052 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Panels View Component renders panel view container with visualizations 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created on
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Edit
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PPL
+
+ }
+ disabled={true}
+ fullWidth={true}
+ onChange={[Function]}
+ onKeyPress={[Function]}
+ placeholder="Use PPL 'where' clauses to add filters on all visualizations [where Carrier = 'OpenSearch-Air']"
+ value=""
+ >
+
+ PPL
+
+ }
+ fullWidth={true}
+ >
+
+
+
+
+
+
+
+
+
+ PPL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 30 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Start by adding
+ your first visualization
+
+
+
+
+
+
+
+
+ Use PPL Queries to fetch & filter observability data and create
+ visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+<<<<<<< HEAD
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+>>>>>>> 6b15239 (Add data test subj to app analytics (#704))
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Panels View Component renders panel view container with visualizations 2`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created on
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Edit
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PPL
+
+ }
+ disabled={true}
+ fullWidth={true}
+ onChange={[Function]}
+ onKeyPress={[Function]}
+ placeholder="Use PPL 'where' clauses to add filters on all visualizations [where Carrier = 'OpenSearch-Air']"
+ value=""
+ >
+
+ PPL
+
+ }
+ fullWidth={true}
+ >
+
+
+
+
+
+
+
+
+
+ PPL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 30 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Start by adding
+ your first visualization
+
+
+
+
+
+
+
+
+ Use PPL Queries to fetch & filter observability data and create
+ visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Panels View Component renders panel view container without visualizations 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created on
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Edit
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Panel actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PPL
+
+ }
+ disabled={true}
+ fullWidth={true}
+ onChange={[Function]}
+ onKeyPress={[Function]}
+ placeholder="Use PPL 'where' clauses to add filters on all visualizations [where Carrier = 'OpenSearch-Air']"
+ value=""
+ >
+
+ PPL
+
+ }
+ fullWidth={true}
+ >
+
+
+
+
+
+
+
+
+
+ PPL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 30 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Start by adding
+ your first visualization
+
+
+
+
+
+
+
+
+ Use PPL Queries to fetch & filter observability data and create
+ visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add Visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+<<<<<<< HEAD
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+>>>>>>> 6b15239 (Add data test subj to app analytics (#704))
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_table.test.tsx b/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_table.test.tsx
new file mode 100644
index 000000000..fb754bba3
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_table.test.tsx
@@ -0,0 +1,82 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { CustomPanelTable } from '../custom_panel_table';
+import { waitFor } from '@testing-library/react';
+import { panelBreadCrumbs, panelsData } from '../../../../test/panels_constants';
+import { CustomPanelListType } from '../../../../common/types/custom_panels';
+
+describe('Panels Table Component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty panel table container', async () => {
+ const loading = false;
+ const fetchCustomPanels = jest.fn();
+ const customPanelData: CustomPanelListType[] = [];
+ const createCustomPanel = jest.fn();
+ const setBreadcrumbs = jest.fn();
+ const parentBreadcrumb = panelBreadCrumbs;
+ const renameCustomPanel = jest.fn();
+ const cloneCustomPanel = jest.fn();
+ const deleteCustomPanelList = jest.fn();
+ const addSamplePanels = jest.fn();
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('renders panel table container', async () => {
+ const loading = false;
+ const fetchCustomPanels = jest.fn();
+ const customPanelData: CustomPanelListType[] = panelsData.panels;
+ const createCustomPanel = jest.fn();
+ const setBreadcrumbs = jest.fn();
+ const parentBreadcrumb = panelBreadCrumbs;
+ const renameCustomPanel = jest.fn();
+ const cloneCustomPanel = jest.fn();
+ const deleteCustomPanelList = jest.fn();
+ const addSamplePanels = jest.fn();
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_view.test.tsx b/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_view.test.tsx
new file mode 100644
index 000000000..3ad38f26d
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/__tests__/custom_panel_view.test.tsx
@@ -0,0 +1,134 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { CustomPanelView } from '../custom_panel_view';
+import { waitFor } from '@testing-library/react';
+import {
+ panelBreadCrumbs,
+ sampleEmptyPanel,
+ samplePanel,
+ samplePPLResponse,
+ sampleSavedVisualization,
+} from '../../../../test/panels_constants';
+import httpClientMock from '../../../../test/__mocks__/httpClientMock';
+import PPLService from '../../../../public/services/requests/ppl';
+import DSLService from '../../../../public/services/requests/dsl';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+import { HttpResponse } from '../../../../../../src/core/public';
+
+describe.skip('Panels View Component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders panel view container without visualizations', async () => {
+ httpClientMock.get = jest.fn(() =>
+ Promise.resolve((sampleEmptyPanel as unknown) as HttpResponse)
+ );
+ const panelId = 'L8Sx53wBDp0rvEg3yoLb';
+ const http = httpClientMock;
+ const pplService = new PPLService(httpClientMock);
+ const dslService = new DSLService(httpClientMock);
+ const core = coreStartMock;
+ const parentBreadcrumbs = panelBreadCrumbs;
+ const start = 'now-30m';
+ const end = 'now';
+ const setStart = jest.fn();
+ const setEnd = jest.fn();
+ const renameCustomPanel = jest.fn();
+ const cloneCustomPanel = jest.fn();
+ const deleteCustomPanel = jest.fn();
+ const setToast = jest.fn();
+ const onEditClick = (savedVisId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisId}`);
+ };
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('renders panel view container with visualizations', async () => {
+ let counter = 0;
+ // Mocks two http get requests first for fetch panel
+ // Others for fetching visualizations in panel
+ httpClientMock.get = jest.fn(() => {
+ if (counter === 0) {
+ counter += 1;
+ return Promise.resolve((samplePanel as unknown) as HttpResponse);
+ } else return Promise.resolve((sampleSavedVisualization as unknown) as HttpResponse);
+ });
+
+ httpClientMock.post = jest.fn(() =>
+ Promise.resolve((samplePPLResponse as unknown) as HttpResponse)
+ );
+ const panelId = 'L8Sx53wBDp0rvEg3yoLb';
+ const http = httpClientMock;
+ const pplService = new PPLService(httpClientMock);
+ const dslService = new DSLService(httpClientMock);
+ const core = coreStartMock;
+ const parentBreadcrumbs = panelBreadCrumbs;
+ const start = 'now-30m';
+ const end = 'now';
+ const setStart = jest.fn();
+ const setEnd = jest.fn();
+ const renameCustomPanel = jest.fn();
+ const cloneCustomPanel = jest.fn();
+ const deleteCustomPanel = jest.fn();
+ const setToast = jest.fn();
+ const onEditClick = (savedVisId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisId}`);
+ };
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/custom_panel_table.tsx b/dashboards-observability/public/components/custom_panels/custom_panel_table.tsx
new file mode 100644
index 000000000..a2c7ce8d6
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/custom_panel_table.tsx
@@ -0,0 +1,413 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import {
+ EuiBreadcrumb,
+ EuiButton,
+ EuiContextMenuItem,
+ EuiContextMenuPanel,
+ EuiFieldSearch,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHorizontalRule,
+ EuiInMemoryTable,
+ EuiLink,
+ EuiOverlayMask,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiPopover,
+ EuiSpacer,
+ EuiTableFieldDataColumnType,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import React, { ReactElement, useEffect, useState } from 'react';
+import moment from 'moment';
+import _ from 'lodash';
+import { ChromeBreadcrumb } from '../../../../../src/core/public';
+import {
+ CREATE_PANEL_MESSAGE,
+ CUSTOM_PANELS_DOCUMENTATION_URL,
+} from '../../../common/constants/custom_panels';
+import { UI_DATE_FORMAT } from '../../../common/constants/shared';
+import { getCustomModal } from './helpers/modal_containers';
+import { CustomPanelListType } from '../../../common/types/custom_panels';
+import { getSampleDataModal } from '../common/helpers/add_sample_modal';
+import { pageStyles } from '../../../common/constants/shared';
+import { DeleteModal } from '../common/helpers/delete_modal';
+
+/*
+ * "CustomPanelTable" module, used to view all the saved panels
+ *
+ * Props taken in as params are:
+ * loading: loader bool for the table
+ * fetchCustomPanels: fetch panels function
+ * customPanels: List of panels available
+ * createCustomPanel: create panel function
+ * setBreadcrumbs: setter for breadcrumbs on top panel
+ * parentBreadcrumb: parent breadcrumb
+ * renameCustomPanel: rename function for the panel
+ * cloneCustomPanel: clone function for the panel
+ * deleteCustomPanelList: delete function for the panels
+ */
+
+interface Props {
+ loading: boolean;
+ fetchCustomPanels: () => void;
+ customPanels: CustomPanelListType[];
+ createCustomPanel: (newCustomPanelName: string) => void;
+ setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
+ parentBreadcrumbs: EuiBreadcrumb[];
+ renameCustomPanel: (newCustomPanelName: string, customPanelId: string) => void;
+ cloneCustomPanel: (newCustomPanelName: string, customPanelId: string) => void;
+ deleteCustomPanelList: (customPanelIdList: string[], toastMessage: string) => any;
+ addSamplePanels: () => void;
+}
+
+export const CustomPanelTable = ({
+ loading,
+ fetchCustomPanels,
+ customPanels,
+ createCustomPanel,
+ setBreadcrumbs,
+ parentBreadcrumbs,
+ renameCustomPanel,
+ cloneCustomPanel,
+ deleteCustomPanelList,
+ addSamplePanels,
+}: Props) => {
+ const [isModalVisible, setIsModalVisible] = useState(false); // Modal Toggle
+ const [modalLayout, setModalLayout] = useState( ); // Modal Layout
+ const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false);
+ const [selectedCustomPanels, setselectedCustomPanels] = useState([]);
+ const [searchQuery, setSearchQuery] = useState('');
+
+ useEffect(() => {
+ setBreadcrumbs(parentBreadcrumbs);
+ fetchCustomPanels();
+ }, []);
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onCreate = async (newCustomPanelName: string) => {
+ createCustomPanel(newCustomPanelName);
+ closeModal();
+ };
+
+ const onRename = async (newCustomPanelName: string) => {
+ renameCustomPanel(newCustomPanelName, selectedCustomPanels[0].id);
+ closeModal();
+ };
+
+ const onClone = async (newName: string) => {
+ cloneCustomPanel(newName, selectedCustomPanels[0].id);
+ closeModal();
+ };
+
+ const onDelete = async () => {
+ const toastMessage = `Custom Panels ${
+ selectedCustomPanels.length > 1 ? 's' : ' ' + selectedCustomPanels[0].name
+ } successfully deleted!`;
+ const PanelList = selectedCustomPanels.map((panel) => panel.id);
+ deleteCustomPanelList(PanelList, toastMessage);
+ closeModal();
+ };
+
+ const createPanel = () => {
+ setModalLayout(
+ getCustomModal(
+ onCreate,
+ closeModal,
+ 'Name',
+ 'Create operational panel',
+ 'Cancel',
+ 'Create',
+ undefined,
+ CREATE_PANEL_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const renamePanel = () => {
+ setModalLayout(
+ getCustomModal(
+ onRename,
+ closeModal,
+ 'Name',
+ 'Rename Panel',
+ 'Cancel',
+ 'Rename',
+ selectedCustomPanels[0].name,
+ CREATE_PANEL_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const clonePanel = () => {
+ setModalLayout(
+ getCustomModal(
+ onClone,
+ closeModal,
+ 'Name',
+ 'Duplicate Panel',
+ 'Cancel',
+ 'Duplicate',
+ selectedCustomPanels[0].name + ' (copy)',
+ CREATE_PANEL_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const deletePanel = () => {
+ const customPanelString = `operational panel${selectedCustomPanels.length > 1 ? 's' : ''}`;
+ setModalLayout(
+
+ );
+ showModal();
+ };
+
+ const addSampledata = async () => {
+ setModalLayout(
+ getSampleDataModal(closeModal, async () => {
+ closeModal();
+ await addSamplePanels();
+ })
+ );
+ showModal();
+ };
+
+ const popoverButton = (
+ setIsActionsPopoverOpen(!isActionsPopoverOpen)}
+ >
+ Actions
+
+ );
+
+ const popoverItems: ReactElement[] = [
+ {
+ setIsActionsPopoverOpen(false);
+ renamePanel();
+ }}
+ >
+ Rename
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ clonePanel();
+ }}
+ >
+ Duplicate
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ deletePanel();
+ }}
+ >
+ Delete
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ addSampledata();
+ }}
+ >
+ Add samples
+ ,
+ ];
+
+ const tableColumns = [
+ {
+ field: 'name',
+ name: 'Name',
+ sortable: true,
+ truncateText: true,
+ render: (value, record) => (
+
+ {_.truncate(value, { length: 100 })}
+
+ ),
+ },
+ {
+ field: 'dateModified',
+ name: 'Last updated',
+ sortable: true,
+ render: (value) => moment(new Date(value)).format(UI_DATE_FORMAT),
+ },
+ {
+ field: 'dateCreated',
+ name: 'Created',
+ sortable: true,
+ render: (value) => moment(new Date(value)).format(UI_DATE_FORMAT),
+ },
+ ] as Array>;
+
+ return (
+
+
+
+
+
+
+ Operational panels
+
+
+
+
+
+
+
+
+ Panels
+ ({customPanels.length})
+
+
+
+
+ Use Operational panels to create and view different visualizations on ingested
+ observability data, using PPL (Piped Processing Language) queries.{' '}
+
+ Learn more
+
+
+
+
+
+
+ setIsActionsPopoverOpen(false)}
+ >
+
+
+
+
+ createPanel()}
+ data-test-subj="customPanels__createNewPanels"
+ >
+ Create panel
+
+
+
+
+
+
+ {customPanels.length > 0 ? (
+ <>
+ setSearchQuery(e.target.value)}
+ />
+
+
+ customPanel.name.toLowerCase().includes(searchQuery.toLowerCase())
+ )
+ : customPanels
+ }
+ itemId="id"
+ columns={tableColumns}
+ tableLayout="auto"
+ pagination={{
+ initialPageSize: 10,
+ pageSizeOptions: [8, 10, 13],
+ }}
+ sorting={{
+ sort: {
+ field: 'dateModified',
+ direction: 'desc',
+ },
+ }}
+ allowNeutralSort={false}
+ isSelectable={true}
+ selection={{
+ onSelectionChange: (items) => setselectedCustomPanels(items),
+ }}
+ />
+ >
+ ) : (
+ <>
+
+
+ No Operational Panels
+
+
+ Use operational panels to dive deeper into observability
+
+ using PPL queries and insightful visualizations
+
+
+
+
+
+ createPanel()}
+ >
+ Create panel
+
+
+
+ addSampledata()}>
+ Add samples
+
+
+
+
+ >
+ )}
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/custom_panel_view.tsx b/dashboards-observability/public/components/custom_panels/custom_panel_view.tsx
new file mode 100644
index 000000000..be6ab6ae9
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/custom_panel_view.tsx
@@ -0,0 +1,672 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import {
+ EuiBreadcrumb,
+ EuiButton,
+ EuiContextMenu,
+ EuiContextMenuPanelDescriptor,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLink,
+ EuiOverlayMask,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContentBody,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiPopover,
+ EuiSpacer,
+ EuiSuperDatePicker,
+ EuiTitle,
+ OnTimeChangeProps,
+ ShortDate,
+} from '@elastic/eui';
+import { last } from 'lodash';
+import React, { useEffect, useState } from 'react';
+import { DurationRange } from '@elastic/eui/src/components/date_picker/types';
+import moment from 'moment';
+import DSLService from '../../services/requests/dsl';
+import { CoreStart } from '../../../../../src/core/public';
+import { EmptyPanelView } from './panel_modules/empty_panel';
+import {
+ CREATE_PANEL_MESSAGE,
+ CUSTOM_PANELS_API_PREFIX,
+} from '../../../common/constants/custom_panels';
+import { SavedVisualizationType, VisualizationType } from '../../../common/types/custom_panels';
+import { PanelGrid } from './panel_modules/panel_grid';
+import { getCustomModal } from './helpers/modal_containers';
+import PPLService from '../../services/requests/ppl';
+import {
+ isDateValid,
+ convertDateTime,
+ onTimeChange,
+ isPPLFilterValid,
+ fetchVisualizationById,
+} from './helpers/utils';
+import { UI_DATE_FORMAT } from '../../../common/constants/shared';
+import { VisaulizationFlyout } from './panel_modules/visualization_flyout';
+import { uiSettingsService } from '../../../common/utils';
+import { PPLReferenceFlyout } from '../common/helpers';
+import { Autocomplete } from '../common/search/autocomplete';
+import {
+ parseGetSuggestions,
+ onItemSelect,
+ parseForIndices,
+} from '../common/search/autocomplete_logic';
+import { AddVisualizationPopover } from './helpers/add_visualization_popover';
+import { DeleteModal } from '../common/helpers/delete_modal';
+
+/*
+ * "CustomPanelsView" module used to render an Operational Panel
+ *
+ * Props taken in as params are:
+ * panelId: Name of the panel opened
+ * page: Page where component is called
+ * http: http core service
+ * pplService: ppl requestor service
+ * dslService: dsl requestor service
+ * chrome: chrome core service
+ * parentBreadcrumb: parent breadcrumb
+ * renameCustomPanel: Rename function for the panel
+ * deleteCustomPanel: Delete function for the panel
+ * cloneCustomPanel: Clone function for the panel
+ * setToast: create Toast function
+ * onEditClick: Edit function for visualization
+ * startTime: Starting time
+ * endTime: Ending time
+ * setStartTime: Function to change start time
+ * setEndTime: Function to change end time
+ * childBreadcrumbs: Breadcrumbs to extend
+ * appId: id of application that panel belongs to
+ * onAddClick: Function for add button instead of add visualization popover
+ */
+
+interface CustomPanelViewProps {
+ panelId: string;
+ page: 'app' | 'operationalPanels';
+ http: CoreStart['http'];
+ pplService: PPLService;
+ dslService: DSLService;
+ chrome: CoreStart['chrome'];
+ parentBreadcrumbs: EuiBreadcrumb[];
+ renameCustomPanel: (editedCustomPanelName: string, editedCustomPanelId: string) => Promise;
+ deleteCustomPanel: (customPanelId: string, customPanelName: string) => Promise;
+ cloneCustomPanel: (clonedCustomPanelName: string, clonedCustomPanelId: string) => Promise;
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void;
+ onEditClick: (savedVisualizationId: string) => any;
+ startTime: string;
+ endTime: string;
+ setStartTime: any;
+ setEndTime: any;
+ childBreadcrumbs?: EuiBreadcrumb[];
+ appId?: string;
+ updateAvailabilityVizId?: any;
+ onAddClick?: any;
+}
+
+export const CustomPanelView = (props: CustomPanelViewProps) => {
+ const {
+ panelId,
+ page,
+ appId,
+ http,
+ pplService,
+ dslService,
+ chrome,
+ parentBreadcrumbs,
+ childBreadcrumbs,
+ startTime,
+ endTime,
+ setStartTime,
+ setEndTime,
+ updateAvailabilityVizId,
+ renameCustomPanel,
+ deleteCustomPanel,
+ cloneCustomPanel,
+ setToast,
+ onEditClick,
+ onAddClick,
+ } = props;
+ const [openPanelName, setOpenPanelName] = useState('');
+ const [panelCreatedTime, setPanelCreatedTime] = useState('');
+ const [pplFilterValue, setPPLFilterValue] = useState('');
+ const [baseQuery, setBaseQuery] = useState('');
+ const [onRefresh, setOnRefresh] = useState(false);
+
+ const [inputDisabled, setInputDisabled] = useState(true);
+ const [addVizDisabled, setAddVizDisabled] = useState(false);
+ const [editDisabled, setEditDisabled] = useState(false);
+ const [dateDisabled, setDateDisabled] = useState(false);
+ const [panelVisualizations, setPanelVisualizations] = useState([]);
+ const [editMode, setEditMode] = useState(false);
+ const [isModalVisible, setIsModalVisible] = useState(false); // Modal Toggle
+ const [modalLayout, setModalLayout] = useState( ); // Modal Layout
+ const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); // Add Visualization Flyout
+ const [isFlyoutReplacement, setisFlyoutReplacement] = useState(false);
+ const [replaceVisualizationId, setReplaceVisualizationId] = useState('');
+ const [panelsMenuPopover, setPanelsMenuPopover] = useState(false);
+ const [editActionType, setEditActionType] = useState('');
+ const [isHelpFlyoutVisible, setHelpIsFlyoutVisible] = useState(false);
+
+ const appPanel = page === 'app';
+
+ const closeHelpFlyout = () => {
+ setAddVizDisabled(false);
+ setHelpIsFlyoutVisible(false);
+ };
+
+ const showHelpFlyout = () => {
+ setAddVizDisabled(true);
+ setHelpIsFlyoutVisible(true);
+ };
+
+ // DateTimePicker States
+ const [recentlyUsedRanges, setRecentlyUsedRanges] = useState([]);
+
+ // Fetch Panel by id
+ const fetchCustomPanel = async () => {
+ return http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/panels/${panelId}`)
+ .then((res) => {
+ setOpenPanelName(res.operationalPanel.name);
+ setPanelCreatedTime(res.createdTimeMs);
+ setPPLFilterValue(res.operationalPanel.queryFilter.query);
+ setStartTime(startTime ? startTime : res.operationalPanel.timeRange.from);
+ setEndTime(endTime ? endTime : res.operationalPanel.timeRange.to);
+ setPanelVisualizations(res.operationalPanel.visualizations);
+ })
+ .catch((err) => {
+ console.error('Issue in fetching the operational panels', err);
+ });
+ };
+
+ const handleQueryChange = (newQuery: string) => {
+ setPPLFilterValue(newQuery);
+ };
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onDatePickerChange = (timeProps: OnTimeChangeProps) => {
+ onTimeChange(
+ timeProps.start,
+ timeProps.end,
+ recentlyUsedRanges,
+ setRecentlyUsedRanges,
+ setStartTime,
+ setEndTime
+ );
+ onRefreshFilters(timeProps.start, timeProps.end);
+ };
+
+ const onDelete = async () => {
+ deleteCustomPanel(panelId, openPanelName).then((res) => {
+ setTimeout(() => {
+ window.location.assign(`${last(parentBreadcrumbs)!.href}`);
+ }, 1000);
+ });
+ closeModal();
+ };
+
+ const deletePanel = () => {
+ setModalLayout(
+
+ );
+ showModal();
+ };
+
+ const onRename = async (newCustomPanelName: string) => {
+ renameCustomPanel(newCustomPanelName, panelId).then(() => {
+ setOpenPanelName(newCustomPanelName);
+ });
+ closeModal();
+ };
+
+ const renamePanel = () => {
+ setModalLayout(
+ getCustomModal(
+ onRename,
+ closeModal,
+ 'Name',
+ 'Rename Panel',
+ 'Cancel',
+ 'Rename',
+ openPanelName,
+ CREATE_PANEL_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const onClone = async (newCustomPanelName: string) => {
+ cloneCustomPanel(newCustomPanelName, panelId).then((id: string) => {
+ window.location.assign(`${last(parentBreadcrumbs)!.href}${id}`);
+ });
+ closeModal();
+ };
+
+ const clonePanel = () => {
+ setModalLayout(
+ getCustomModal(
+ onClone,
+ closeModal,
+ 'Name',
+ 'Duplicate Panel',
+ 'Cancel',
+ 'Duplicate',
+ openPanelName + ' (copy)',
+ CREATE_PANEL_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ // toggle between panel edit mode
+ const editPanel = (editType: string) => {
+ setEditMode(!editMode);
+ if (editType === 'cancel') fetchCustomPanel();
+ setEditActionType(editType);
+ };
+
+ const closeFlyout = () => {
+ setIsFlyoutVisible(false);
+ setAddVizDisabled(false);
+ checkDisabledInputs();
+ };
+
+ const showFlyout = (isReplacement?: boolean, replaceVizId?: string) => {
+ setisFlyoutReplacement(isReplacement);
+ setReplaceVisualizationId(replaceVizId);
+ setIsFlyoutVisible(true);
+ setAddVizDisabled(true);
+ setInputDisabled(true);
+ };
+
+ const checkDisabledInputs = () => {
+ // When not in edit mode and panel has no visualizations
+ if (panelVisualizations.length === 0 && !editMode) {
+ setEditDisabled(true);
+ setInputDisabled(true);
+ setAddVizDisabled(false);
+ setDateDisabled(false);
+ }
+
+ // When panel has visualizations
+ if (panelVisualizations.length > 0) {
+ setEditDisabled(false);
+ setInputDisabled(false);
+ setAddVizDisabled(false);
+ setDateDisabled(false);
+ }
+
+ // When in edit mode
+ if (editMode) {
+ setEditDisabled(false);
+ setInputDisabled(true);
+ setAddVizDisabled(true);
+ setDateDisabled(true);
+ }
+ };
+
+ const buildBaseQuery = async () => {
+ const indices: string[] = [];
+ for (let i = 0; i < panelVisualizations.length; i++) {
+ const visualizationId = panelVisualizations[i].savedVisualizationId;
+ // TODO: create route to get list of visualizations in one call
+ const visData: SavedVisualizationType = await fetchVisualizationById(
+ http,
+ visualizationId,
+ (value: string) => setToast(value, 'danger')
+ );
+ const moreIndices = parseForIndices(visData.query);
+ for (let j = 0; j < moreIndices.length; j++) {
+ if (!indices.includes(moreIndices[j])) {
+ indices.push(moreIndices[j]);
+ }
+ }
+ }
+ setBaseQuery('source = ' + indices.join(', '));
+ return;
+ };
+
+ const onRefreshFilters = (start: ShortDate, end: ShortDate) => {
+ if (!isDateValid(convertDateTime(start), convertDateTime(end, false), setToast)) {
+ return;
+ }
+
+ if (!isPPLFilterValid(pplFilterValue, setToast)) {
+ return;
+ }
+
+ const panelFilterBody = {
+ panelId,
+ query: pplFilterValue,
+ language: 'ppl',
+ to: end,
+ from: start,
+ };
+
+ http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels/filter`, {
+ body: JSON.stringify(panelFilterBody),
+ })
+ .then((res) => {
+ setOnRefresh(!onRefresh);
+ })
+ .catch((err) => {
+ setToast('Error is adding filters to the operational panel', 'danger');
+ console.error(err.body.message);
+ });
+ };
+
+ const cloneVisualization = (visualzationTitle: string, savedVisualizationId: string) => {
+ http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/visualizations`, {
+ body: JSON.stringify({
+ panelId,
+ savedVisualizationId,
+ }),
+ })
+ .then(async (res) => {
+ setPanelVisualizations(res.visualizations);
+ setToast(`Visualization ${visualzationTitle} successfully added!`, 'success');
+ })
+ .catch((err) => {
+ setToast(`Error in adding ${visualzationTitle} visualization to the panel`, 'danger');
+ console.error(err);
+ });
+ };
+
+ const cancelButton = (
+ editPanel('cancel')}>
+ Cancel
+
+ );
+
+ const saveButton = (
+ editPanel('save')}>
+ Save
+
+ );
+
+ const editButton = (
+ editPanel('edit')} disabled={editDisabled}>
+ Edit
+
+ );
+
+ const addButton = (
+
+ Add
+
+ );
+
+ // Panel Actions Button
+ const panelActionsButton = (
+ setPanelsMenuPopover(true)}
+ disabled={addVizDisabled}
+ >
+ Panel actions
+
+ );
+
+ let flyout;
+ if (isFlyoutVisible) {
+ flyout = (
+
+ );
+ }
+
+ let helpFlyout;
+ if (isHelpFlyoutVisible) {
+ helpFlyout = ;
+ }
+
+ const panelActionsMenu: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Panel actions',
+ items: [
+ {
+ name: 'Reload panel',
+ onClick: () => {
+ setPanelsMenuPopover(false);
+ fetchCustomPanel();
+ },
+ },
+ {
+ name: 'Rename panel',
+ onClick: () => {
+ setPanelsMenuPopover(false);
+ renamePanel();
+ },
+ },
+ {
+ name: 'Duplicate panel',
+ onClick: () => {
+ setPanelsMenuPopover(false);
+ clonePanel();
+ },
+ },
+ {
+ name: 'Delete panel',
+ onClick: () => {
+ setPanelsMenuPopover(false);
+ deletePanel();
+ },
+ },
+ ],
+ },
+ ];
+
+ // Fetch the custom panel on Initial Mount
+ useEffect(() => {
+ fetchCustomPanel();
+ }, [panelId]);
+
+ // Toggle input type (disabled or not disabled)
+ // Disabled when there no visualizations in panels or when the panel is in edit mode
+ useEffect(() => {
+ checkDisabledInputs();
+ }, [editMode]);
+
+ // Build base query with all of the indices included in the current visualizations
+ useEffect(() => {
+ checkDisabledInputs();
+ buildBaseQuery();
+ }, [panelVisualizations]);
+
+ // Edit the breadcrumb when panel name changes
+ useEffect(() => {
+ let newBreadcrumb;
+ if (childBreadcrumbs) {
+ newBreadcrumb = childBreadcrumbs;
+ } else {
+ newBreadcrumb = [
+ {
+ text: openPanelName,
+ href: `${last(parentBreadcrumbs)!.href}${panelId}`,
+ },
+ ];
+ }
+ chrome.setBreadcrumbs([...parentBreadcrumbs, ...newBreadcrumb]);
+ }, [panelId, openPanelName]);
+
+ return (
+
+
+
+
+ {appPanel || (
+ <>
+
+
+ {openPanelName}
+
+
+
+
+ Created on {moment(panelCreatedTime).format(UI_DATE_FORMAT)}
+
+
+
+ {editMode ? (
+ <>
+ {cancelButton}
+ {saveButton}
+ >
+ ) : (
+ {editButton}
+ )}
+
+ setPanelsMenuPopover(false)}
+ >
+
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+ onRefreshFilters(startTime, endTime)}
+ dslService={dslService}
+ getSuggestions={parseGetSuggestions}
+ onItemSelect={onItemSelect}
+ isDisabled={inputDisabled}
+ tabId={'panels-filter'}
+ placeholder={
+ "Use PPL 'where' clauses to add filters on all visualizations [where Carrier = 'OpenSearch-Air']"
+ }
+ possibleCommands={[{ label: 'where' }]}
+ append={
+
+ PPL
+
+ }
+ />
+
+
+
+
+ {appPanel && (
+ <>
+ {editMode ? (
+ <>
+ {cancelButton}
+ {saveButton}
+ >
+ ) : (
+ {editButton}
+ )}
+ {addButton}
+ >
+ )}
+
+
+ {panelVisualizations.length === 0 && (
+
+ )}
+
+
+
+
+ {isModalVisible && modalLayout}
+ {flyout}
+ {helpFlyout}
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/custom_input_model.test.tsx.snap b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/custom_input_model.test.tsx.snap
new file mode 100644
index 000000000..bbc895db3
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/custom_input_model.test.tsx.snap
@@ -0,0 +1,100 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Custom Input Model component renders custom input modal with multiple arguments 1`] = `
+
+
+
+
+ Input test
+
+
+
+
+
+
+
+
+
+
+
+ btn test
+
+
+ btn test 2
+
+
+
+
+`;
+
+exports[`Custom Input Model component renders custom input modal with single argument 1`] = `
+
+
+
+
+ Input test
+
+
+
+
+
+
+
+
+
+
+
+ btn test
+
+
+ btn test 2
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/modal_container.test.tsx.snap b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/modal_container.test.tsx.snap
new file mode 100644
index 000000000..3d92156d3
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/modal_container.test.tsx.snap
@@ -0,0 +1,64 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Modal Container component renders DeleteModal component 1`] = `
+
+
+
+
+ Test Title
+
+
+
+
+ Test Message
+
+
+ The action cannot be undone.
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+ Delete
+
+
+
+
+`;
+
+exports[`Modal Container component renders getCloneModal function 1`] = `""`;
+
+exports[`Modal Container component renders getDeleteModal function 1`] = `""`;
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap
new file mode 100644
index 000000000..039fcd1b7
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap
@@ -0,0 +1,3152 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Utils helper functions renders displayVisualization function 1`] = `
+
+
+
+
+
+
+
+`;
+
+exports[`Utils helper functions renders displayVisualization function 2`] = `
+
+`;
+
+exports[`Utils helper functions renders displayVisualization function 3`] = `
+
+`;
+
+exports[`Utils helper functions renders displayVisualization function 3`] = `
+
+`;
+
+exports[`Utils helper functions renders displayVisualization function 4`] = `
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/custom_input_model.test.tsx b/dashboards-observability/public/components/custom_panels/helpers/__tests__/custom_input_model.test.tsx
new file mode 100644
index 000000000..11659128c
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/custom_input_model.test.tsx
@@ -0,0 +1,61 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { CustomInputModal } from '../custom_input_modal';
+
+describe('Custom Input Model component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders custom input modal with single argument', () => {
+ const runModal = jest.fn;
+ const closeModal = jest.fn();
+ const labelTxt = 'test label';
+ const titletxt = 'Input test';
+ const btn1txt = 'btn test';
+ const btn2txt = 'btn test 2';
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders custom input modal with multiple arguments', () => {
+ const runModal = jest.fn;
+ const closeModal = jest.fn();
+ const labelTxt = 'test label';
+ const titletxt = 'Input test';
+ const btn1txt = 'btn test';
+ const btn2txt = 'btn test 2';
+ const openPanelName = 'Test Panel';
+ const helpText = 'Help Text';
+ const optionalArgs = ['option1', 'option2', 'option3'];
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/modal_container.test.tsx b/dashboards-observability/public/components/custom_panels/helpers/__tests__/modal_container.test.tsx
new file mode 100644
index 000000000..0fb8c3bb0
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/modal_container.test.tsx
@@ -0,0 +1,42 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { DeleteModal } from '../../../common/helpers/delete_modal';
+import React from 'react';
+import { getCloneModal, getDeleteModal } from '../modal_containers';
+
+describe('Modal Container component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders getCloneModal function', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const wrapper = shallow(getCloneModal(onCancel, onConfirm));
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders getDeleteModal function', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const title = 'Test Title';
+ const message = 'Test Message';
+ const confirmMessage = 'Confirm Message';
+ const wrapper = shallow(getDeleteModal(onCancel, onConfirm, title, message, confirmMessage));
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders DeleteModal component', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const title = 'Test Title';
+ const message = 'Test Message';
+ const wrapper = shallow(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/utils.test.tsx b/dashboards-observability/public/components/custom_panels/helpers/__tests__/utils.test.tsx
new file mode 100644
index 000000000..0e92e37e7
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/utils.test.tsx
@@ -0,0 +1,122 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import moment from 'moment';
+import { DurationRange } from '@elastic/eui/src/components/date_picker/types';
+
+import {
+ isNameValid,
+ convertDateTime,
+ mergeLayoutAndVisualizations,
+ onTimeChange,
+ isDateValid,
+ isPPLFilterValid,
+ displayVisualization,
+} from '../utils';
+import {
+ sampleLayout,
+ sampleMergedVisualizations,
+ samplePanelVisualizations,
+ samplePPLEmptyResponse,
+ samplePPLResponse,
+ sampleSavedVisualization,
+} from '../../../../../test/panels_constants';
+import { PPL_DATE_FORMAT } from '../../../../../common/constants/shared';
+import React from 'react';
+
+describe.skip('Utils helper functions', () => {
+ configure({ adapter: new Adapter() });
+
+ it('validates isNameValid function', () => {
+ expect(isNameValid('Lorem ipsum dolor sit amet, consectetur adipiscing elit,')).toBe(false);
+ expect(isNameValid('Lorem ipsum dolor sit amet, consectetur adipiscin')).toBe(true);
+ });
+
+ it('validates convertDateTime function', () => {
+ expect(convertDateTime('2022-01-30T18:44:40.577Z')).toBe(
+ moment('2022-01-30T18:44:40.577Z').format(PPL_DATE_FORMAT)
+ );
+ expect(convertDateTime('2022-02-25T19:18:33.075Z', true)).toBe(
+ moment('2022-02-25T19:18:33.075Z').format(PPL_DATE_FORMAT)
+ );
+ });
+
+ it('validates mergeLayoutAndVisualizations function', () => {
+ const setState = jest.fn();
+ mergeLayoutAndVisualizations(sampleLayout, samplePanelVisualizations, setState);
+ expect(setState).toHaveBeenCalledWith(sampleMergedVisualizations);
+ });
+
+ it('validates onTimeChange function', () => {
+ const setRecentlyUsedRanges = jest.fn((x) => x);
+ const setStart = jest.fn();
+ const setEnd = jest.fn();
+ const recentlyUsedRanges: DurationRange[] = [];
+ onTimeChange(
+ '2022-01-30T18:44:40.577Z',
+ '2022-02-25T19:18:33.075Z',
+ recentlyUsedRanges,
+ setRecentlyUsedRanges,
+ setStart,
+ setEnd
+ );
+ expect(setRecentlyUsedRanges).toHaveBeenCalledWith([
+ { start: '2022-01-30T18:44:40.577Z', end: '2022-02-25T19:18:33.075Z' },
+ ]);
+ expect(setStart).toHaveBeenCalledWith('2022-01-30T18:44:40.577Z');
+ expect(setEnd).toHaveBeenCalledWith('2022-02-25T19:18:33.075Z');
+ });
+
+ it('validates isDateValid function', () => {
+ const setToast = jest.fn();
+ expect(
+ isDateValid(
+ convertDateTime('2022-01-30T18:44:40.577Z'),
+ convertDateTime('2022-02-25T19:18:33.075Z', false),
+ setToast
+ )
+ ).toBe(true);
+ expect(
+ isDateValid(
+ convertDateTime('2022-01-30T18:44:40.577Z'),
+ convertDateTime('2022-01-30T18:44:40.577Z', false),
+ setToast
+ )
+ ).toBe(true);
+ expect(
+ isDateValid(
+ convertDateTime('2022-02-25T19:18:33.075Z'),
+ convertDateTime('2022-01-30T18:44:40.577Z', false),
+ setToast
+ )
+ ).toBe(false);
+ });
+
+ it('validates isPPLFilterValid function', () => {
+ const setToast = jest.fn();
+ expect(isPPLFilterValid(sampleSavedVisualization.visualization.query, setToast)).toBe(false);
+ expect(isPPLFilterValid("where Carrier = 'OpenSearch-Air'", setToast)).toBe(true);
+ });
+
+ it('renders displayVisualization function', () => {
+ const wrapper1 = mount({displayVisualization(samplePPLResponse, 'bar', false)}
);
+ expect(wrapper1).toMatchSnapshot();
+
+ const wrapper2 = mount({displayVisualization(samplePPLResponse, 'line', true)}
);
+ expect(wrapper2).toMatchSnapshot();
+
+ const wrapper3 = mount(
+ {displayVisualization(samplePPLResponse, 'horizontal_bar', false)}
+ );
+ expect(wrapper3).toMatchSnapshot();
+
+ const wrapper4 = mount(
+ {displayVisualization(samplePPLEmptyResponse, 'horizontal_bar', true)}
+ );
+ expect(wrapper4).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/helpers/add_visualization_popover.tsx b/dashboards-observability/public/components/custom_panels/helpers/add_visualization_popover.tsx
new file mode 100644
index 000000000..b59b1c43d
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/add_visualization_popover.tsx
@@ -0,0 +1,82 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui';
+import React, { useState } from 'react';
+
+interface AddVisualizationPopoverProps {
+ showFlyout: (isReplacement?: boolean, replaceVizId?: string) => void;
+ addVizDisabled: boolean;
+}
+
+export const AddVisualizationPopover = ({
+ addVizDisabled,
+ showFlyout,
+}: AddVisualizationPopoverProps) => {
+ const [isVizPopoverOpen, setVizPopoverOpen] = useState(false); // Add Visualization Popover
+
+ const onPopoverClick = () => {
+ setVizPopoverOpen(!isVizPopoverOpen);
+ };
+
+ const closeVizPopover = () => {
+ setVizPopoverOpen(false);
+ };
+
+ const advancedVisualization = () => {
+ closeVizPopover();
+ window.location.assign('#/event_analytics/explorer');
+ };
+
+ const getVizContextPanels = () => {
+ return [
+ {
+ id: 0,
+ title: 'Add visualization',
+ items: [
+ {
+ name: 'Select existing visualization',
+ onClick: () => {
+ if (closeVizPopover != null) {
+ closeVizPopover();
+ }
+ showFlyout();
+ },
+ },
+ {
+ name: 'Create new visualization',
+ onClick: () => {
+ advancedVisualization();
+ },
+ },
+ ],
+ },
+ ];
+ };
+
+ const addVisualizationButton = (
+
+ Add visualization
+
+ );
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/helpers/custom_input_modal.tsx b/dashboards-observability/public/components/custom_panels/helpers/custom_input_modal.tsx
new file mode 100644
index 000000000..15042e679
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/custom_input_modal.tsx
@@ -0,0 +1,109 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import {
+ EuiButtonEmpty,
+ EuiForm,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiOverlayMask,
+ EuiFormRow,
+ EuiFieldText,
+ EuiButton,
+} from '@elastic/eui';
+
+/*
+ * "CustomInputModalProps" component is used to create a modal with an input filed
+ *
+ * Props taken in as params are:
+ * runModal - function to fetch input field value and trigger closing modal
+ * closeModal - function to trigger closing modal
+ * titletxt - string as header for title of modal
+ * labelTxt - string as header for input field
+ * btn1txt - string as content to fill "close button"
+ * btn2txt - string as content to fill "confirm button"
+ * openPanelName - Default input value for the field
+ * helpText - string help for the input field
+ * optionalArgs - Arguments needed to pass them to runModal function
+ */
+
+type CustomInputModalProps = {
+ runModal:
+ | ((value: string, value2: string, value3: string, value4: string) => void)
+ | ((value: string) => void);
+ closeModal: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void;
+ labelTxt: string;
+ titletxt: string;
+ btn1txt: string;
+ btn2txt: string;
+ openPanelName?: string;
+ helpText?: string;
+ optionalArgs?: string[];
+};
+
+export const CustomInputModal = (props: CustomInputModalProps) => {
+ const {
+ runModal,
+ closeModal,
+ labelTxt,
+ titletxt,
+ btn1txt,
+ btn2txt,
+ openPanelName,
+ helpText,
+ optionalArgs,
+ } = props;
+ const [value, setValue] = useState(openPanelName || ''); // sets input value
+
+ const onChange = (e: React.ChangeEvent) => {
+ setValue(e.target.value);
+ };
+
+ return (
+
+
+
+ {titletxt}
+
+
+
+
+
+ onChange(e)}
+ />
+
+
+
+
+
+ {btn1txt}
+ {optionalArgs === undefined ? (
+ runModal(value)} fill>
+ {btn2txt}
+
+ ) : (
+ runModal(value, ...optionalArgs)}
+ fill
+ >
+ {btn2txt}
+
+ )}
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/helpers/modal_containers.tsx b/dashboards-observability/public/components/custom_panels/helpers/modal_containers.tsx
new file mode 100644
index 000000000..0fb80a597
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/modal_containers.tsx
@@ -0,0 +1,107 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import {
+ EuiOverlayMask,
+ EuiConfirmModal,
+ EuiButton,
+ EuiButtonEmpty,
+ EuiFieldText,
+ EuiForm,
+ EuiFormRow,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiText,
+ EuiSpacer,
+} from '@elastic/eui';
+import { CustomInputModal } from './custom_input_modal';
+
+/* The file contains helper functions for modal layouts
+ * getCustomModal - returns modal with input field
+ * getCloneModal - returns a confirm-modal with clone option
+ * getDeleteModal - returns a confirm-modal with delete option
+ */
+
+export const getCustomModal = (
+ runModal:
+ | ((value: string, value2: string, value3: string, value4: string) => void)
+ | ((value: string) => void),
+ closeModal: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ labelTxt: string,
+ titletxt: string,
+ btn1txt: string,
+ btn2txt: string,
+ openPanelName?: string,
+ helpText?: string,
+ optionalArgs?: string[]
+) => {
+ return (
+
+ );
+};
+
+export const getCloneModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void
+) => {
+ return (
+
+
+ Do you want to clone this operational panel?
+
+
+ );
+};
+
+export const getDeleteModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void,
+ title: string,
+ message: string,
+ confirmMessage?: string
+) => {
+ return (
+
+
+ {message}
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/helpers/utils.tsx b/dashboards-observability/public/components/custom_panels/helpers/utils.tsx
new file mode 100644
index 000000000..3121ddeee
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/helpers/utils.tsx
@@ -0,0 +1,306 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+
+import dateMath from '@elastic/datemath';
+import { ShortDate } from '@elastic/eui';
+import { DurationRange } from '@elastic/eui/src/components/date_picker/types';
+import _ from 'lodash';
+import { Moment } from 'moment-timezone';
+import React from 'react';
+import { Layout } from 'react-grid-layout';
+import { PPL_DATE_FORMAT, PPL_INDEX_REGEX } from '../../../../common/constants/shared';
+import PPLService from '../../../services/requests/ppl';
+import { CoreStart } from '../../../../../../src/core/public';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../common/constants/custom_panels';
+import { VisualizationType, SavedVisualizationType } from '../../../../common/types/custom_panels';
+import { Visualization } from '../../visualizations/visualization';
+import { getVizContainerProps } from '../../../components/visualizations/charts/helpers';
+
+/*
+ * "Utils" This file contains different reused functions in operational panels
+ *
+ * isNameValid - Validates string to length > 0 and < 50
+ * convertDateTime - Converts input datetime string to required format
+ * mergeLayoutAndVisualizations - Function to merge current panel layout into the visualizations list
+ * getQueryResponse - Get response of PPL query to load visualizations
+ * renderSavedVisualization - Fetches savedVisualization by Id and runs getQueryResponse
+ * onTimeChange - Function to store recently used time filters and set start and end time.
+ * isDateValid - Function to check date validity
+ * isPPLFilterValid - Validate if the panel PPL query doesn't contain any Index/Time/Field filters
+ * displayVisualization - Function to render the visualzation based of its type
+ */
+
+// Name validation 0>Name<=50
+export const isNameValid = (name: string) => {
+ return name.length >= 50 || name.length === 0 ? false : true;
+};
+
+// DateTime convertor to required format
+export const convertDateTime = (datetime: string, isStart = true, formatted = true) => {
+ let returnTime: undefined | Moment;
+ if (isStart) {
+ returnTime = dateMath.parse(datetime);
+ } else {
+ returnTime = dateMath.parse(datetime, { roundUp: true });
+ }
+
+ if (formatted) return returnTime!.utc().format(PPL_DATE_FORMAT);
+ return returnTime;
+};
+
+// Merges new layout into visualizations
+export const mergeLayoutAndVisualizations = (
+ layout: Layout[],
+ newVisualizationList: VisualizationType[],
+ setPanelVisualizations: (value: React.SetStateAction) => void
+) => {
+ const newPanelVisualizations: VisualizationType[] = [];
+
+ for (let i = 0; i < newVisualizationList.length; i++) {
+ for (let j = 0; j < layout.length; j++) {
+ if (newVisualizationList[i].id == layout[j].i) {
+ newPanelVisualizations.push({
+ ...newVisualizationList[i],
+ x: layout[j].x,
+ y: layout[j].y,
+ w: layout[j].w,
+ h: layout[j].h,
+ });
+ }
+ }
+ }
+ setPanelVisualizations(newPanelVisualizations);
+};
+
+/* Builds Final Query by adding time and query filters(From panel UI) to the original visualization query
+ * -> Final Query is as follows:
+ * -> finalQuery = indexPartOfQuery + timeQueryFilter + panelFilterQuery + filterPartOfQuery
+ * -> finalQuery = source=opensearch_dashboards_sample_data_flights
+ * + | where utc_time > ‘2021-07-01 00:00:00’ and utc_time < ‘2021-07-02 00:00:00’
+ * + | where Carrier='OpenSearch-Air'
+ * + | stats sum(FlightDelayMin) as delays by Carrier
+ */
+const queryAccumulator = (
+ originalQuery: string,
+ timestampField: string,
+ startTime: string,
+ endTime: string,
+ panelFilterQuery: string
+) => {
+ const indexMatchArray = originalQuery.match(PPL_INDEX_REGEX);
+ if (indexMatchArray == null) {
+ throw Error('index not found in Query');
+ }
+ const indexPartOfQuery = indexMatchArray[0];
+ const filterPartOfQuery = originalQuery.replace(PPL_INDEX_REGEX, '');
+ const timeQueryFilter = ` | where ${timestampField} >= '${convertDateTime(
+ startTime
+ )}' and ${timestampField} <= '${convertDateTime(endTime, false)}'`;
+ const pplFilterQuery = panelFilterQuery === '' ? '' : ` | ${panelFilterQuery}`;
+ return indexPartOfQuery + timeQueryFilter + pplFilterQuery + filterPartOfQuery;
+};
+
+// PPL Service requestor
+const pplServiceRequestor = async (
+ pplService: PPLService,
+ finalQuery: string,
+ type: string,
+ setVisualizationData: React.Dispatch>,
+ setIsLoading: React.Dispatch>,
+ setIsError: React.Dispatch>
+) => {
+ await pplService
+ .fetch({ query: finalQuery, format: 'viz' })
+ .then((res) => {
+ if (res === undefined) setIsError('Please check the validity of PPL Filter');
+ setVisualizationData(res);
+ })
+ .catch((error: Error) => {
+ setIsError(error.stack || 'Issue in fetching visualization');
+ console.error(error);
+ })
+ .finally(() => {
+ setIsLoading(false);
+ });
+};
+
+// Fetched Saved Visualization By Id
+export const fetchVisualizationById = async (
+ http: CoreStart['http'],
+ savedVisualizationId: string,
+ setIsError: (value: string) => void
+) => {
+ let savedVisualization = {} as SavedVisualizationType;
+ await http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/visualizations/${savedVisualizationId}`)
+ .then((res) => {
+ savedVisualization = res.visualization;
+ })
+ .catch((err) => {
+ setIsError(`Could not locate saved visualization id:${savedVisualizationId}`);
+ console.error('Issue in fetching the saved Visualization by Id', err);
+ });
+
+ return savedVisualization;
+};
+
+// Get PPL Query Response
+export const getQueryResponse = (
+ pplService: PPLService,
+ query: string,
+ type: string,
+ startTime: string,
+ endTime: string,
+ setVisualizationData: React.Dispatch>,
+ setIsLoading: React.Dispatch>,
+ setIsError: React.Dispatch>,
+ filterQuery = '',
+ timestampField = 'timestamp'
+) => {
+ setIsLoading(true);
+ setIsError('');
+
+ let finalQuery = '';
+ try {
+ finalQuery = queryAccumulator(query, timestampField, startTime, endTime, filterQuery);
+ } catch (error) {
+ const errorMessage = 'Issue in building final query';
+ setIsError(errorMessage);
+ console.error(errorMessage, error);
+ setIsLoading(false);
+ return;
+ }
+
+ pplServiceRequestor(pplService, finalQuery, type, setVisualizationData, setIsLoading, setIsError);
+};
+
+// Fetches savedVisualization by Id and runs getQueryResponse
+export const renderSavedVisualization = async (
+ http: CoreStart['http'],
+ pplService: PPLService,
+ savedVisualizationId: string,
+ startTime: string,
+ endTime: string,
+ filterQuery: string,
+ setVisualizationTitle: React.Dispatch>,
+ setVisualizationType: React.Dispatch>,
+ setVisualizationData: React.Dispatch>,
+ setVisualizationMetaData: React.Dispatch>,
+ setIsLoading: React.Dispatch>,
+ setIsError: React.Dispatch>
+) => {
+ setIsLoading(true);
+ setIsError('');
+
+ let visualization = {} as SavedVisualizationType;
+ visualization = await fetchVisualizationById(http, savedVisualizationId, setIsError);
+
+ if (_.isEmpty(visualization)) {
+ setIsLoading(false);
+ return;
+ }
+
+ if (visualization.name) {
+ setVisualizationTitle(visualization.name);
+ }
+
+ if (visualization.type) {
+ setVisualizationType(visualization.type);
+ }
+
+ setVisualizationMetaData(visualization);
+
+ getQueryResponse(
+ pplService,
+ visualization.query,
+ visualization.type,
+ startTime,
+ endTime,
+ setVisualizationData,
+ setIsLoading,
+ setIsError,
+ filterQuery,
+ visualization.timeField
+ );
+};
+
+// Function to store recently used time filters and set start and end time.
+export const onTimeChange = (
+ start: ShortDate,
+ end: ShortDate,
+ recentlyUsedRanges: DurationRange[],
+ setRecentlyUsedRanges: React.Dispatch>,
+ setStart: React.Dispatch>,
+ setEnd: React.Dispatch>
+) => {
+ const recentlyUsedRange = recentlyUsedRanges.filter((recentlyUsedRange) => {
+ const isDuplicate = recentlyUsedRange.start === start && recentlyUsedRange.end === end;
+ return !isDuplicate;
+ });
+ recentlyUsedRange.unshift({ start, end });
+ setStart(start);
+ setEnd(end);
+ setRecentlyUsedRanges(recentlyUsedRange.slice(0, 9));
+};
+
+// Function to check date validity
+export const isDateValid = (
+ start: string | Moment | undefined,
+ end: string | Moment | undefined,
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void,
+ side?: string | undefined
+) => {
+ if (end! < start!) {
+ setToast('Time range entered is invalid', 'danger', undefined, side);
+ return false;
+ } else return true;
+};
+
+// Check for time filter in query
+const checkIndexExists = (query: string) => {
+ return PPL_INDEX_REGEX.test(query);
+};
+
+// Check PPL Query in Panel UI
+// Validate if the query doesn't contain any Index
+export const isPPLFilterValid = (
+ query: string,
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void
+) => {
+ if (checkIndexExists(query)) {
+ setToast('Please remove index from PPL Filter', 'danger', undefined);
+ return false;
+ }
+ return true;
+};
+
+// Renders visualization in the vizualization container component
+export const displayVisualization = (metaData: any, data: any, type: string) => {
+ if (metaData === undefined || metaData === {}) {
+ return <>>;
+ }
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/home.tsx b/dashboards-observability/public/components/custom_panels/home.tsx
new file mode 100644
index 000000000..4a5395fb0
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/home.tsx
@@ -0,0 +1,349 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+
+import { EuiBreadcrumb, EuiGlobalToastList, EuiLink, ShortDate } from '@elastic/eui';
+import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
+import _ from 'lodash';
+import React, { ReactChild, useState } from 'react';
+// eslint-disable-next-line @osd/eslint/module_migration
+import { StaticContext } from 'react-router';
+import { Route, RouteComponentProps } from 'react-router-dom';
+import PPLService from '../../services/requests/ppl';
+import DSLService from '../../services/requests/dsl';
+import { CoreStart } from '../../../../../src/core/public';
+import {
+ CUSTOM_PANELS_API_PREFIX,
+ CUSTOM_PANELS_DOCUMENTATION_URL,
+} from '../../../common/constants/custom_panels';
+import {
+ EVENT_ANALYTICS,
+ OBSERVABILITY_BASE,
+ SAVED_OBJECTS,
+} from '../../../common/constants/shared';
+import { CustomPanelListType } from '../../../common/types/custom_panels';
+import { ObservabilitySideBar } from '../common/side_nav';
+import { CustomPanelTable } from './custom_panel_table';
+import { CustomPanelView } from './custom_panel_view';
+import { isNameValid } from './helpers/utils';
+
+/*
+ * "Home" module is initial page for Operantional Panels
+ *
+ * Props taken in as params are:
+ * http: http core service;
+ * chrome: chrome core service;
+ * parentBreadcrumb: parent breadcrumb name and link
+ * pplService: ppl requestor service
+ * renderProps: Props from router
+ */
+
+interface PanelHomeProps {
+ http: CoreStart['http'];
+ chrome: CoreStart['chrome'];
+ parentBreadcrumbs: EuiBreadcrumb[];
+ pplService: PPLService;
+ dslService: DSLService;
+ renderProps: RouteComponentProps;
+}
+
+export const Home = ({
+ http,
+ chrome,
+ parentBreadcrumbs,
+ pplService,
+ dslService,
+ renderProps,
+}: PanelHomeProps) => {
+ const [customPanelData, setcustomPanelData] = useState([]);
+ const [toasts, setToasts] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [toastRightSide, setToastRightSide] = useState(true);
+ const [start, setStart] = useState('');
+ const [end, setEnd] = useState('');
+
+ const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => {
+ if (!text) text = '';
+ setToastRightSide(!side ? true : false);
+ setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]);
+ };
+
+ const onEditClick = (savedVisualizationId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisualizationId}`);
+ };
+
+ // Fetches all saved Custom Panels
+ const fetchCustomPanels = () => {
+ setLoading(true);
+ http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/panels`)
+ .then((res) => {
+ setcustomPanelData(res.panels);
+ })
+ .catch((err) => {
+ console.error('Issue in fetching the operational panels', err.body.message);
+ });
+ setLoading(false);
+ };
+
+ // Creates a new CustomPanel
+ const createCustomPanel = (newCustomPanelName: string) => {
+ if (!isNameValid(newCustomPanelName)) {
+ setToast('Invalid Operational Panel name', 'danger');
+ return;
+ }
+
+ return http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels`, {
+ body: JSON.stringify({
+ panelName: newCustomPanelName,
+ }),
+ })
+ .then(async (res) => {
+ setToast(`Operational Panel "${newCustomPanelName}" successfully created!`);
+ window.location.assign(`${_.last(parentBreadcrumbs)!.href}${res.newPanelId}`);
+ })
+ .catch((err) => {
+ setToast(
+ 'Please ask your administrator to enable Operational Panels for you.',
+ 'danger',
+
+ Documentation
+
+ );
+ console.error(err);
+ });
+ };
+
+ // Renames an existing CustomPanel
+ const renameCustomPanel = (editedCustomPanelName: string, editedCustomPanelId: string) => {
+ if (!isNameValid(editedCustomPanelName)) {
+ setToast('Invalid Custom Panel name', 'danger');
+ return Promise.reject();
+ }
+ const renamePanelObject = {
+ panelId: editedCustomPanelId,
+ panelName: editedCustomPanelName,
+ };
+
+ return http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels/rename`, {
+ body: JSON.stringify(renamePanelObject),
+ })
+ .then((res) => {
+ setcustomPanelData((prevCustomPanelData) => {
+ const newCustomPanelData = [...prevCustomPanelData];
+ const renamedCustomPanel = newCustomPanelData.find(
+ (customPanel) => customPanel.id === editedCustomPanelId
+ );
+ if (renamedCustomPanel) renamedCustomPanel.name = editedCustomPanelName;
+ return newCustomPanelData;
+ });
+ setToast(`Operational Panel successfully renamed into "${editedCustomPanelName}"`);
+ })
+ .catch((err) => {
+ setToast(
+ 'Error renaming Operational Panel, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Clones an existing Custom Panel, return new Custom Panel id
+ const cloneCustomPanel = (
+ clonedCustomPanelName: string,
+ clonedCustomPanelId: string
+ ): Promise => {
+ if (!isNameValid(clonedCustomPanelName)) {
+ setToast('Invalid Operational Panel name', 'danger');
+ return Promise.reject();
+ }
+ const clonePanelObject = {
+ panelId: clonedCustomPanelId,
+ panelName: clonedCustomPanelName,
+ };
+
+ return http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels/clone`, {
+ body: JSON.stringify(clonePanelObject),
+ })
+ .then((res) => {
+ setcustomPanelData((prevCustomPanelData) => {
+ return [
+ ...prevCustomPanelData,
+ {
+ name: clonedCustomPanelName,
+ id: res.clonePanelId,
+ dateCreated: res.dateCreated,
+ dateModified: res.dateModified,
+ },
+ ];
+ });
+ setToast(`Operational Panel "${clonedCustomPanelName}" successfully created!`);
+ return res.clonePanelId;
+ })
+ .catch((err) => {
+ setToast(
+ 'Error cloning Operational Panel, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Deletes multiple existing Operational Panels
+ const deleteCustomPanelList = (customPanelIdList: string[], toastMessage: string) => {
+ const concatList = customPanelIdList.toString();
+ return http
+ .delete(`${CUSTOM_PANELS_API_PREFIX}/panelList/` + concatList)
+ .then((res) => {
+ setcustomPanelData((prevCustomPanelData) => {
+ return prevCustomPanelData.filter(
+ (customPanel) => !customPanelIdList.includes(customPanel.id)
+ );
+ });
+ setToast(toastMessage);
+ return res;
+ })
+ .catch((err) => {
+ setToast(
+ 'Error deleting Operational Panels, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Deletes an existing Operational Panel
+ const deleteCustomPanel = (customPanelId: string, customPanelName: string) => {
+ return http
+ .delete(`${CUSTOM_PANELS_API_PREFIX}/panels/` + customPanelId)
+ .then((res) => {
+ setcustomPanelData((prevCustomPanelData) => {
+ return prevCustomPanelData.filter((customPanel) => customPanel.id !== customPanelId);
+ });
+ setToast(`Operational Panel "${customPanelName}" successfully deleted!`);
+ return res;
+ })
+ .catch((err) => {
+ setToast(
+ 'Error deleting Operational Panel, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ const addSamplePanels = async () => {
+ try {
+ setLoading(true);
+ const flights = await http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_flights',
+ },
+ })
+ .then((resp) => resp.total === 0);
+ const logs = await http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_logs',
+ },
+ })
+ .then((resp) => resp.total === 0);
+ if (flights || logs) setToast('Adding sample data. This can take some time.');
+ await Promise.all([
+ flights ? http.post('../api/sample_data/flights') : Promise.resolve(),
+ logs ? http.post('../api/sample_data/logs') : Promise.resolve(),
+ ]);
+
+ let savedVisualizationIds: string[] = [];
+ await http
+ .get(`${OBSERVABILITY_BASE}${EVENT_ANALYTICS}${SAVED_OBJECTS}/addSampleSavedObjects/panels`)
+ .then((resp) => (savedVisualizationIds = [...resp.savedVizIds]));
+
+ await http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/panels/addSamplePanels`, {
+ body: JSON.stringify({
+ savedVisualizationIds,
+ }),
+ })
+ .then((res) => {
+ setcustomPanelData([...customPanelData, ...res.demoPanelsData]);
+ });
+ setToast(`Sample panels successfully added.`);
+ } catch (err: any) {
+ setToast('Error adding sample panels.', 'danger');
+ console.error(err.body.message);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ {
+ setToasts(toasts.filter((toast) => toast.id !== removedToast.id));
+ }}
+ side={toastRightSide ? 'right' : 'left'}
+ toastLifeTimeMs={6000}
+ />
+ {
+ return (
+
+
+
+ );
+ }}
+ />
+ {
+ return (
+
+ );
+ }}
+ />
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/__snapshots__/empty_panel.test.tsx.snap b/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/__snapshots__/empty_panel.test.tsx.snap
new file mode 100644
index 000000000..9a31cb5f0
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/__snapshots__/empty_panel.test.tsx.snap
@@ -0,0 +1,430 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Empty panel view component renders empty panel view with disabled popover 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Start by adding your first visualization
+
+
+
+
+
+
+
+
+ Use PPL Queries to fetch & filter observability data and create visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Empty panel view component renders empty panel view with enabled popover 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Start by adding your first visualization
+
+
+
+
+
+
+
+
+ Use PPL Queries to fetch & filter observability data and create visualizations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add visualization
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="addVisualizationContextMenu"
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/empty_panel.test.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/empty_panel.test.tsx
new file mode 100644
index 000000000..2c3c24dcd
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/__tests__/empty_panel.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui';
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { EmptyPanelView } from '../empty_panel';
+
+describe('Empty panel view component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty panel view with disabled popover', () => {
+ const addVizDisabled = true;
+ const showFlyout = jest.fn();
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('EuiButton').prop('disabled')).toBe(true);
+ });
+
+ it('renders empty panel view with enabled popover', () => {
+ const addVizDisabled = false;
+ const showFlyout = jest.fn();
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('EuiButton').prop('disabled')).toBe(false);
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/empty_panel.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/empty_panel.tsx
new file mode 100644
index 000000000..32a1226b7
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/empty_panel.tsx
@@ -0,0 +1,46 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiSpacer, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import React, { useState } from 'react';
+import { AddVisualizationPopover } from '../helpers/add_visualization_popover';
+
+/*
+ * EmptyPanelView - This Sub-component is shown to the user when a operational panel is empty
+ *
+ * Props taken in as params are:
+ * addVizDisabled -> Boolean to enable/disable the add visualization button
+ * getVizContextPanels -> Function to populate the add visualization popover
+ */
+
+interface EmptyPanelViewProps {
+ addButton?: any;
+ addVizDisabled: boolean;
+ showFlyout: (isReplacement?: boolean, replaceVizId?: string) => void;
+}
+
+export const EmptyPanelView = ({
+ addVizDisabled,
+ showFlyout,
+ addButton = ,
+}: EmptyPanelViewProps) => {
+ return (
+
+
+
+ Start by adding your first visualization
+
+
+ Use PPL Queries to fetch & filter observability data and create visualizations
+
+
+
+
+ {addButton}
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/__snapshots__/panel_grid.test.tsx.snap b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/__snapshots__/panel_grid.test.tsx.snap
new file mode 100644
index 000000000..b192dff2d
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/__snapshots__/panel_grid.test.tsx.snap
@@ -0,0 +1,174 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Panel Grid Component renders panel grid component with empty visualizations 1`] = `
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/panel_grid.test.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/panel_grid.test.tsx
new file mode 100644
index 000000000..1366eb453
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/__tests__/panel_grid.test.tsx
@@ -0,0 +1,63 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import httpClientMock from '../../../../../../test/__mocks__/httpClientMock';
+import { PanelGrid } from '../panel_grid';
+import PPLService from '../../../../../services/requests/ppl';
+import { VisualizationType } from '../../../../../../common/types/custom_panels';
+import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks';
+import { waitFor } from '@testing-library/react';
+
+describe('Panel Grid Component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders panel grid component with empty visualizations', async () => {
+ const http = httpClientMock;
+ const core = coreStartMock;
+ const panelId = '';
+ const panelVisualizations: VisualizationType[] = [];
+ const setPanelVisualizations = jest.fn();
+ const editMode = false;
+ const pplService = new PPLService(httpClientMock);
+ const start = 'now-15m';
+ const end = 'now';
+ const onRefresh = false;
+ const cloneVisualization = jest.fn();
+ const pplFilterValue = '';
+ const showFlyout = jest.fn();
+ const editActionType = '';
+ const onEditClick = (savedVisId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisId}`);
+ };
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/index.ts b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/index.ts
new file mode 100644
index 000000000..d67fc2054
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { PanelGrid } from "./panel_grid";
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.scss b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.scss
new file mode 100644
index 000000000..0c00cee0b
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.scss
@@ -0,0 +1,15 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.react-grid-layout {
+ & .react-grid-placeholder {
+ background: $euiColorWarning;
+ }
+}
+
+.full-width {
+ min-width: 100%;
+ max-width: 100%;
+}
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.tsx
new file mode 100644
index 000000000..dc70ba7fd
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/panel_grid/panel_grid.tsx
@@ -0,0 +1,212 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+/* eslint-disable no-console */
+
+import _ from 'lodash';
+import React, { useEffect, useState } from 'react';
+import { Layout, Layouts, Responsive, WidthProvider } from 'react-grid-layout';
+import useObservable from 'react-use/lib/useObservable';
+import { CoreStart } from '../../../../../../../src/core/public';
+import PPLService from '../../../../services/requests/ppl';
+import { VisualizationContainer } from '../visualization_container';
+import { VisualizationType } from '../../../../../common/types/custom_panels';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../../common/constants/custom_panels';
+import './panel_grid.scss';
+import { mergeLayoutAndVisualizations } from '../../helpers/utils';
+
+// HOC container to provide dynamic width for Grid layout
+const ResponsiveGridLayout = WidthProvider(Responsive);
+
+/*
+ * PanelGrid - This module is places all visualizations in react-grid-layout
+ *
+ * Props taken in as params are:
+ * http: http core service;
+ * chrome: chrome core service;
+ * panelId: OpenPanel Id
+ * updateAvailabilityVizId: function to update application if availabilityViz is removed from panel
+ * panelVisualizations: list of panel visualizations
+ * setPanelVisualizations: function to set panel visualizations
+ * editMode: boolean to check if the panel is in edit mode
+ * pplService: ppl requestor service
+ * startTime: start time in date filter
+ * endTime: end time in date filter
+ * onRefresh: boolean value to trigger refresh of visualizations
+ * cloneVisualization: function to clone a visualization in panel
+ * pplFilterValue: string with panel PPL filter value
+ * showFlyout: function to show the flyout
+ * editActionType: Type of action done while clicking the edit button
+ */
+
+interface PanelGridProps {
+ http: CoreStart['http'];
+ chrome: CoreStart['chrome'];
+ panelId: string;
+ updateAvailabilityVizId?: any;
+ panelVisualizations: VisualizationType[];
+ setPanelVisualizations: React.Dispatch>;
+ editMode: boolean;
+ pplService: PPLService;
+ startTime: string;
+ endTime: string;
+ onEditClick: (savedVisualizationId: string) => any;
+ onRefresh: boolean;
+ cloneVisualization: (visualzationTitle: string, savedVisualizationId: string) => void;
+ pplFilterValue: string;
+ showFlyout: (isReplacement?: boolean | undefined, replaceVizId?: string | undefined) => void;
+ editActionType: string;
+ setEditVizId?: any;
+}
+
+export const PanelGrid = (props: PanelGridProps) => {
+ const {
+ http,
+ chrome,
+ panelId,
+ updateAvailabilityVizId,
+ panelVisualizations,
+ setPanelVisualizations,
+ editMode,
+ pplService,
+ startTime,
+ endTime,
+ onEditClick,
+ onRefresh,
+ cloneVisualization,
+ pplFilterValue,
+ showFlyout,
+ editActionType,
+ } = props;
+ const [currentLayout, setCurrentLayout] = useState([]);
+ const [postEditLayout, setPostEditLayout] = useState([]);
+ const [gridData, setGridData] = useState(panelVisualizations.map(() => <>>));
+ const isLocked = useObservable(chrome.getIsNavDrawerLocked$());
+
+ // Reset Size of Visualizations when layout is changed
+ const layoutChanged = (currLayouts: Layout[], allLayouts: Layouts) => {
+ window.dispatchEvent(new Event('resize'));
+ setPostEditLayout(currLayouts);
+ };
+
+ const loadVizComponents = () => {
+ const gridDataComps = panelVisualizations.map(
+ (panelVisualization: VisualizationType, index) => (
+
+ )
+ );
+ setGridData(gridDataComps);
+ };
+
+ // Reload the Layout
+ const reloadLayout = () => {
+ const tempLayout: Layout[] = panelVisualizations.map((panelVisualization) => {
+ return {
+ i: panelVisualization.id,
+ x: panelVisualization.x,
+ y: panelVisualization.y,
+ w: panelVisualization.w,
+ h: panelVisualization.h,
+ static: !editMode,
+ } as Layout;
+ });
+ setCurrentLayout(tempLayout);
+ };
+
+ // remove visualization from panel in edit mode
+ const removeVisualization = (visualizationId: string) => {
+ const newVisualizationList = _.reject(panelVisualizations, {
+ id: visualizationId,
+ });
+ mergeLayoutAndVisualizations(postEditLayout, newVisualizationList, setPanelVisualizations);
+ };
+
+ // Save Visualization Layouts when not in edit mode anymore (after users saves the panel)
+ const saveVisualizationLayouts = async (panelID: string, visualizationParams: any) => {
+ return http
+ .put(`${CUSTOM_PANELS_API_PREFIX}/visualizations/edit`, {
+ body: JSON.stringify({
+ panelId: panelID,
+ visualizationParams,
+ }),
+ })
+ .then(async (res) => {
+ setPanelVisualizations(res.visualizations);
+ })
+ .catch((err) => {
+ console.error(err);
+ });
+ };
+
+ // Update layout whenever user edit gets completed
+ useEffect(() => {
+ if (editMode) {
+ reloadLayout();
+ loadVizComponents();
+ }
+ }, [editMode]);
+
+ useEffect(() => {
+ if (editActionType === 'save') {
+ const visualizationParams = postEditLayout.map((layout) =>
+ _.omit(layout, ['static', 'moved'])
+ );
+ saveVisualizationLayouts(panelId, visualizationParams);
+ if (updateAvailabilityVizId) {
+ updateAvailabilityVizId(panelVisualizations);
+ }
+ }
+ }, [editActionType]);
+
+ // Update layout whenever visualizations are updated
+ useEffect(() => {
+ reloadLayout();
+ loadVizComponents();
+ }, [panelVisualizations]);
+
+ // Reset Size of Panel Grid when Nav Dock is Locked
+ useEffect(() => {
+ setTimeout(function () {
+ window.dispatchEvent(new Event('resize'));
+ }, 300);
+ }, [isLocked]);
+
+ useEffect(() => {
+ loadVizComponents();
+ }, [onRefresh]);
+
+ useEffect(() => {
+ loadVizComponents();
+ }, []);
+
+ return (
+
+ {panelVisualizations.map((panelVisualization: VisualizationType, index) => (
+ {gridData[index]}
+ ))}
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/__snapshots__/visualization_container.test.tsx.snap b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/__snapshots__/visualization_container.test.tsx.snap
new file mode 100644
index 000000000..3065c1cb8
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/__snapshots__/visualization_container.test.tsx.snap
@@ -0,0 +1,303 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization Container Component renders add visualization container 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Visualization Container Component renders add visualization container 2`] = `
+
+
+ >>>>>> 6b15239 (Add data test subj to app analytics (#704))
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/visualization_container.test.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/visualization_container.test.tsx
new file mode 100644
index 000000000..20ab07fa9
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/__tests__/visualization_container.test.tsx
@@ -0,0 +1,69 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import PPLService from '../../../../../services/requests/ppl';
+import React from 'react';
+import { VisualizationContainer } from '../visualization_container';
+import httpClientMock from '../../../../../../test/__mocks__/httpClientMock';
+import { HttpResponse } from '../../../../../../../../src/core/public';
+import { waitFor } from '@testing-library/react';
+import {
+ sampleSavedVisualization,
+ samplePPLResponse,
+} from '../../../../../../test/panels_constants';
+
+describe.skip('Visualization Container Component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders add visualization container', async () => {
+ httpClientMock.get = jest.fn(() =>
+ Promise.resolve((sampleSavedVisualization as unknown) as HttpResponse)
+ );
+
+ httpClientMock.post = jest.fn(() =>
+ Promise.resolve((samplePPLResponse as unknown) as HttpResponse)
+ );
+
+ const editMode = true;
+ const visualizationId = 'panel_viz_9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d';
+ const savedVisualizationId = 'oiuccXwBYVazWqOO1e06';
+ const fromTime = 'now-15m';
+ const toTime = 'now';
+ const onRefresh = true;
+ const cloneVisualization = jest.fn();
+ const pplFilterValue = 'where Carrier = "OpenSearch-Air"';
+ const showFlyout = jest.fn();
+ const removeVisualization = jest.fn();
+ const pplService = new PPLService(httpClientMock);
+ const onEditClick = (savedVisId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisId}`);
+ };
+
+ const wrapper = mount(
+
+ );
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/index.ts b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/index.ts
new file mode 100644
index 000000000..1503aa7ab
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { VisualizationContainer } from "./visualization_container";
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.scss b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.scss
new file mode 100644
index 000000000..6d14d7288
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.scss
@@ -0,0 +1,60 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.mouseGrabber {
+ & :hover {
+ cursor: -webkit-grab;
+ cursor: grab;
+ }
+ & :active {
+ cursor: -webkit-grabbing;
+ cursor: grabbing;
+ }
+}
+
+.visualization-action-button {
+ & :hover {
+ cursor: -webkit-pointer;
+ cursor: pointer;
+ }
+}
+
+.visualization-div {
+ width: 100%;
+ height: 90%;
+ overflow: auto;
+ text-align: center;
+}
+
+%center-div {
+ top: 50%;
+ left: 50%;
+ -ms-transform: translate(-50%, -50%);
+ -moz-transform: translate(-50%, -50%);
+ -webkit-transform: translate(-50%, -50%);
+ -o-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+}
+
+.visualization-loading-chart {
+ margin: 0;
+ position: absolute;
+ @extend %center-div;
+}
+
+.visualization-error-div {
+ overflow: auto;
+ position: relative;
+ @extend %center-div;
+}
+
+.panel-full-width {
+ width: 100%;
+ height: 100%;
+}
+
+.panels-title-text {
+ @include euiTextTruncate;
+}
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.tsx
new file mode 100644
index 000000000..bb1a25e04
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_container/visualization_container.tsx
@@ -0,0 +1,222 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButtonIcon,
+ EuiContextMenuItem,
+ EuiContextMenuPanel,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiIcon,
+ EuiLoadingChart,
+ EuiPanel,
+ EuiPopover,
+ EuiSpacer,
+ EuiText,
+ EuiToolTip,
+} from '@elastic/eui';
+import React, { useEffect, useMemo, useState } from 'react';
+import { CoreStart } from '../../../../../../../src/core/public';
+import PPLService from '../../../../services/requests/ppl';
+import { displayVisualization, renderSavedVisualization } from '../../helpers/utils';
+import './visualization_container.scss';
+
+/*
+ * Visualization container - This module is a placeholder to add visualizations in react-grid-layout
+ *
+ * Props taken in as params are:
+ * editMode: boolean to check if the panel is in edit mode
+ * visualizationId: unique visualization id
+ * visualizationTitle: visualization name
+ * query: ppl query to load the visualization
+ * pplService: ppl requestor service
+ * type: type of visualization [bar, horizontal_bar, line]
+ * fromTime: start time in date filter
+ * toTime: end time in date filter
+ * onRefresh: boolean value to trigger refresh of visualizations
+ * cloneVisualization: function to clone a visualization in panel
+ * pplFilterValue: string with panel PPL filter value
+ * showFlyout: function to show the flyout
+ * removeVisualization: function to remove all the visualizations
+ */
+
+interface Props {
+ http: CoreStart['http'];
+ editMode: boolean;
+ visualizationId: string;
+ savedVisualizationId: string;
+ pplService: PPLService;
+ fromTime: string;
+ toTime: string;
+ onRefresh: boolean;
+ pplFilterValue: string;
+ usedInNotebooks?: boolean;
+ onEditClick: (savedVisualizationId: string) => any;
+ cloneVisualization?: (visualzationTitle: string, savedVisualizationId: string) => void;
+ showFlyout?: (isReplacement?: boolean | undefined, replaceVizId?: string | undefined) => void;
+ removeVisualization?: (visualizationId: string) => void;
+}
+
+export const VisualizationContainer = ({
+ http,
+ editMode,
+ visualizationId,
+ savedVisualizationId,
+ pplService,
+ fromTime,
+ toTime,
+ onRefresh,
+ pplFilterValue,
+ usedInNotebooks,
+ onEditClick,
+ cloneVisualization,
+ showFlyout,
+ removeVisualization,
+}: Props) => {
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+ const [disablePopover, setDisablePopover] = useState(false);
+ const [visualizationTitle, setVisualizationTitle] = useState('');
+ const [visualizationType, setVisualizationType] = useState('');
+ const [visualizationMetaData, setVisualizationMetaData] = useState();
+ const [visualizationData, setVisualizationData] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [isError, setIsError] = useState('');
+ const onActionsMenuClick = () => setIsPopoverOpen((currPopoverOpen) => !currPopoverOpen);
+ const closeActionsMenu = () => setIsPopoverOpen(false);
+
+ let popoverPanel = [
+ {
+ closeActionsMenu();
+ onEditClick(savedVisualizationId);
+ }}
+ >
+ Edit
+ ,
+ {
+ closeActionsMenu();
+ showFlyout(true, visualizationId);
+ }}
+ >
+ Replace
+ ,
+ {
+ closeActionsMenu();
+ cloneVisualization(visualizationTitle, savedVisualizationId);
+ }}
+ >
+ Duplicate
+ ,
+ ];
+
+ if (usedInNotebooks) {
+ popoverPanel = [popoverPanel[0]];
+ }
+
+ const loadVisaulization = async () => {
+ await renderSavedVisualization(
+ http,
+ pplService,
+ savedVisualizationId,
+ fromTime,
+ toTime,
+ pplFilterValue,
+ setVisualizationTitle,
+ setVisualizationType,
+ setVisualizationData,
+ setVisualizationMetaData,
+ setIsLoading,
+ setIsError
+ );
+ };
+
+ const memoisedVisualizationBox = useMemo(
+ () => (
+
+ {isLoading ? (
+
+ ) : isError !== '' ? (
+
+ ) : (
+ displayVisualization(visualizationMetaData, visualizationData, visualizationType)
+ )}
+
+ ),
+ [onRefresh, isLoading, isError, visualizationData, visualizationType, visualizationMetaData]
+ );
+
+ useEffect(() => {
+ loadVisaulization();
+ }, [onRefresh]);
+
+ useEffect(() => {
+ editMode ? setDisablePopover(true) : setDisablePopover(false);
+ }, [editMode]);
+
+ return (
+
+
+
+
+
+
+ {visualizationTitle}
+
+
+
+
+ {disablePopover ? (
+ {
+ removeVisualization(visualizationId);
+ }}
+ />
+ ) : (
+
+ }
+ isOpen={isPopoverOpen}
+ closePopover={closeActionsMenu}
+ anchorPosition="downLeft"
+ >
+
+
+ )}
+
+
+
+ {memoisedVisualizationBox}
+
+ );
+};
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/__snapshots__/visualization_flyout.test.tsx.snap b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/__snapshots__/visualization_flyout.test.tsx.snap
new file mode 100644
index 000000000..1d43d5228
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/__snapshots__/visualization_flyout.test.tsx.snap
@@ -0,0 +1,2140 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization Flyout Component renders add visualization Flyout 1`] = `
+
+
+
+ No saved visualizations found!
+
+
+ }
+ >
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+ }
+ flyoutFooter={
+
+
+
+
+ Cancel
+
+
+
+
+ Add
+
+
+
+
+ }
+ flyoutHeader={
+
+
+
+ Select existing visualization
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ sideCar={
+ Object {
+ "assignMedium": [Function],
+ "assignSyncMedium": [Function],
+ "options": Object {
+ "async": true,
+ "ssr": false,
+ },
+ "read": [Function],
+ "useMedium": [Function],
+ }
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ sideCar={
+ Object {
+ "assignMedium": [Function],
+ "assignSyncMedium": [Function],
+ "options": Object {
+ "async": true,
+ "ssr": false,
+ },
+ "read": [Function],
+ "useMedium": [Function],
+ }
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select existing visualization
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Visualization Flyout Component renders replace visualization Flyout 1`] = `
+
+
+
+ No saved visualizations found!
+
+
+ }
+ >
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+ }
+ flyoutFooter={
+
+
+
+
+ Cancel
+
+
+
+
+ Add
+
+
+
+
+ }
+ flyoutHeader={
+
+
+
+ Replace visualization
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ sideCar={
+ Object {
+ "assignMedium": [Function],
+ "assignSyncMedium": [Function],
+ "options": Object {
+ "async": true,
+ "ssr": false,
+ },
+ "read": [Function],
+ "useMedium": [Function],
+ }
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ sideCar={
+ Object {
+ "assignMedium": [Function],
+ "assignSyncMedium": [Function],
+ "options": Object {
+ "async": true,
+ "ssr": false,
+ },
+ "read": [Function],
+ "useMedium": [Function],
+ }
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+ }
+ onActivation={[Function]}
+ onDeactivation={[Function]}
+ persistentFocus={false}
+ returnFocus={[Function]}
+ shards={Array []}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Replace visualization
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+ No saved visualizations found!
+
+
+
+
+
+
+
+
+ Please use the "create new visualization" option in add visualization menu.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/visualization_flyout.test.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/visualization_flyout.test.tsx
new file mode 100644
index 000000000..7aebf7b90
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/__tests__/visualization_flyout.test.tsx
@@ -0,0 +1,76 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import PPLService from '../../../../../services/requests/ppl';
+import React from 'react';
+import { VisaulizationFlyout } from '../visualization_flyout';
+import httpClientMock from '../../../../../../test/__mocks__/httpClientMock';
+import { ShortDate } from '@elastic/eui';
+
+describe('Visualization Flyout Component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders add visualization Flyout', () => {
+ const panelId = '';
+ const pplFilterValue = '';
+ const start: ShortDate = 'now-15m';
+ const end: ShortDate = 'now';
+ const setToast = jest.fn();
+ const closeFlyout = jest.fn();
+ const setPanelVisualizations = jest.fn();
+ const pplService = new PPLService(httpClientMock);
+ const isFlyoutReplacement = false;
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders replace visualization Flyout', () => {
+ const panelId = 'oiuccXwBYVazWqOO1e06';
+ const pplFilterValue = "where Carrier='OpenSearch-Air'";
+ const start: ShortDate = '2011-08-11T01:23:45.678Z';
+ const end: ShortDate = '2011-08-12T01:23:45.678Z';
+ const setToast = jest.fn();
+ const closeFlyout = jest.fn();
+ const setPanelVisualizations = jest.fn();
+ const pplService = new PPLService(httpClientMock);
+ const isFlyoutReplacement = true;
+ const replaceVisualizationId = '';
+
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/index.ts b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/index.ts
new file mode 100644
index 000000000..bab4d36c5
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { VisaulizationFlyout } from "./visualization_flyout";
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.scss b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.scss
new file mode 100644
index 000000000..bec49407b
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.scss
@@ -0,0 +1,29 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.visualization-div-preview {
+ min-height: 50vh;
+}
+
+.visualization-loading-chart-preview {
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ -ms-transform: translate(-50%, -50%);
+ -moz-transform: translate(-50%, -50%);
+ -webkit-transform: translate(-50%, -50%);
+ -o-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+}
+
+.visualization-error-div-preview {
+ overflow: scroll;
+}
+
+.date-picker-preview {
+ height: 3vh;
+ max-width: 500px;
+}
diff --git a/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.tsx b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.tsx
new file mode 100644
index 000000000..2c97e7095
--- /dev/null
+++ b/dashboards-observability/public/components/custom_panels/panel_modules/visualization_flyout/visualization_flyout.tsx
@@ -0,0 +1,369 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import {
+ EuiButton,
+ EuiButtonIcon,
+ EuiCallOut,
+ EuiDatePicker,
+ EuiDatePickerRange,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFlyoutBody,
+ EuiFlyoutFooter,
+ EuiFlyoutHeader,
+ EuiFormRow,
+ EuiIcon,
+ EuiLoadingChart,
+ EuiSelect,
+ EuiSelectOption,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+ ShortDate,
+} from '@elastic/eui';
+import _ from 'lodash';
+import React, { useEffect, useState } from 'react';
+import { FlyoutContainers } from '../../../common/flyout_containers';
+import { displayVisualization, getQueryResponse, isDateValid } from '../../helpers/utils';
+import { convertDateTime } from '../../helpers/utils';
+import PPLService from '../../../../services/requests/ppl';
+import { CoreStart } from '../../../../../../../src/core/public';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../../common/constants/custom_panels';
+import {
+ pplResponse,
+ SavedVisualizationType,
+ VisualizationType,
+} from '../../../../../common/types/custom_panels';
+import './visualization_flyout.scss';
+import { uiSettingsService } from '../../../../../common/utils';
+
+/*
+ * VisaulizationFlyout - This module create a flyout to add visualization
+ *
+ * Props taken in as params are:
+ * panelId: panel Id of current operational panel
+ * closeFlyout: function to close the flyout
+ * start: start time in date filter
+ * end: end time in date filter
+ * setToast: function to set toast in the panel
+ * http: http core service
+ * pplService: ppl requestor service
+ * setPanelVisualizations: function set the visualization list in panel
+ * isFlyoutReplacement: boolean to see if the flyout is trigger for add or replace visualization
+ * replaceVisualizationId: string id of the visualization to be replaced
+ */
+
+interface VisualizationFlyoutProps {
+ panelId: string;
+ pplFilterValue: string;
+ closeFlyout: () => void;
+ start: ShortDate;
+ end: ShortDate;
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void;
+ http: CoreStart['http'];
+ pplService: PPLService;
+ setPanelVisualizations: React.Dispatch>;
+ isFlyoutReplacement?: boolean | undefined;
+ replaceVisualizationId?: string | undefined;
+ appId?: string;
+}
+
+export const VisaulizationFlyout = ({
+ panelId,
+ appId = '',
+ pplFilterValue,
+ closeFlyout,
+ start,
+ end,
+ setToast,
+ http,
+ pplService,
+ setPanelVisualizations,
+ isFlyoutReplacement,
+ replaceVisualizationId,
+}: VisualizationFlyoutProps) => {
+ const [newVisualizationTitle, setNewVisualizationTitle] = useState('');
+ const [newVisualizationType, setNewVisualizationType] = useState('');
+ const [newVisualizationTimeField, setNewVisualizationTimeField] = useState('');
+ const [previewMetaData, setPreviewMetaData] = useState();
+ const [pplQuery, setPPLQuery] = useState('');
+ const [previewData, setPreviewData] = useState({} as pplResponse);
+ const [previewArea, setPreviewArea] = useState(<>>);
+ const [previewLoading, setPreviewLoading] = useState(false);
+ const [isPreviewError, setIsPreviewError] = useState('');
+ const [savedVisualizations, setSavedVisualizations] = useState([]);
+ const [visualizationOptions, setVisualizationOptions] = useState([]);
+ const [selectValue, setSelectValue] = useState('');
+
+ // DateTimePicker States
+ const startDate = convertDateTime(start, true, false);
+ const endDate = convertDateTime(end, false, false);
+
+ const isInputValid = () => {
+ if (!isDateValid(convertDateTime(start), convertDateTime(end, false), setToast, 'left')) {
+ return false;
+ }
+
+ if (selectValue === '') {
+ setToast('Please make a valid selection', 'danger', undefined, 'left');
+ return false;
+ }
+
+ return true;
+ };
+
+ const addVisualization = () => {
+ if (!isInputValid()) return;
+
+ if (isFlyoutReplacement) {
+ http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/visualizations/replace`, {
+ body: JSON.stringify({
+ panelId,
+ savedVisualizationId: selectValue,
+ oldVisualizationId: replaceVisualizationId,
+ }),
+ })
+ .then(async (res) => {
+ setPanelVisualizations(res.visualizations);
+ setToast(`Visualization ${newVisualizationTitle} successfully added!`, 'success');
+ })
+ .catch((err) => {
+ setToast(`Error in adding ${newVisualizationTitle} visualization to the panel`, 'danger');
+ console.error(err);
+ });
+ } else {
+ http
+ .post(`${CUSTOM_PANELS_API_PREFIX}/visualizations`, {
+ body: JSON.stringify({
+ panelId,
+ savedVisualizationId: selectValue,
+ }),
+ })
+ .then(async (res) => {
+ setPanelVisualizations(res.visualizations);
+ setToast(`Visualization ${newVisualizationTitle} successfully added!`, 'success');
+ })
+ .catch((err) => {
+ setToast(`Error in adding ${newVisualizationTitle} visualization to the panel`, 'danger');
+ console.error(err);
+ });
+ }
+ closeFlyout();
+ };
+
+ const onRefreshPreview = () => {
+ if (!isInputValid()) return;
+
+ getQueryResponse(
+ pplService,
+ pplQuery,
+ newVisualizationType,
+ start,
+ end,
+ setPreviewData,
+ setPreviewLoading,
+ setIsPreviewError,
+ pplFilterValue,
+ newVisualizationTimeField
+ );
+ };
+
+ const timeRange = (
+
+ endDate}
+ aria-label="Start date"
+ dateFormat={uiSettingsService.get('dateFormat')}
+ />
+ }
+ endDateControl={
+ endDate}
+ aria-label="End date"
+ dateFormat={uiSettingsService.get('dateFormat')}
+ />
+ }
+ />
+
+ );
+
+ const flyoutHeader = (
+
+
+
+ {isFlyoutReplacement ? 'Replace visualization' : 'Select existing visualization'}
+
+
+
+ );
+
+ const onChangeSelection = (e: React.ChangeEvent) => {
+ setSelectValue(e.target.value);
+ };
+
+ const emptySavedVisualizations = (
+
+ No saved visualizations found!
+
+ );
+
+ const flyoutBody =
+ savedVisualizations.length > 0 ? (
+
+ <>
+
+
+ onChangeSelection(e)}
+ options={visualizationOptions}
+ />
+
+
+
+
+
+ Preview
+
+
+
+
+
+
+
+ {previewArea}
+ >
+
+ ) : (
+
+ <>
+ {'Please use the "create new visualization" option in add visualization menu.'}
+ >
+
+ );
+
+ const flyoutFooter = (
+
+
+
+ Cancel
+
+
+
+ Add
+
+
+
+
+ );
+
+ // Fetch all saved visualizations
+ const fetchSavedVisualizations = async () => {
+ return http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/visualizations`)
+ .then((res) => {
+ if (res.visualizations.length > 0) {
+ setSavedVisualizations(res.visualizations);
+ const filterAppVis = res.visualizations.filter((vis: SavedVisualizationType) => {
+ return appId
+ ? vis.hasOwnProperty('application_id')
+ ? vis.application_id === appId
+ : false
+ : !vis.hasOwnProperty('application_id');
+ });
+ setVisualizationOptions(
+ filterAppVis.map((visualization: SavedVisualizationType) => {
+ return { value: visualization.id, text: visualization.name };
+ })
+ );
+ }
+ })
+ .catch((err) => {
+ console.error('Issue in fetching the operational panels', err);
+ });
+ };
+
+ useEffect(() => {
+ const previewTemplate = (
+ <>
+ {timeRange}
+
+
+ {previewLoading ? (
+
+ ) : isPreviewError !== '' ? (
+
+
+
+
+ {isPreviewError}
+
+
+ ) : (
+
+ {displayVisualization(previewMetaData, previewData, newVisualizationType)}
+
+ )}
+
+
+ >
+ );
+ setPreviewArea(previewTemplate);
+ }, [previewLoading]);
+
+ // On change of selected visualization change options
+ useEffect(() => {
+ for (let i = 0; i < savedVisualizations.length; i++) {
+ const visualization = savedVisualizations[i];
+ if (visualization.id === selectValue) {
+ setPPLQuery(visualization.query);
+ setNewVisualizationTitle(visualization.name);
+ setNewVisualizationType(visualization.type);
+ setPreviewMetaData(visualization);
+ setNewVisualizationTimeField(visualization.timeField);
+ break;
+ }
+ }
+ }, [selectValue]);
+
+ // load saved visualizations
+ useEffect(() => {
+ fetchSavedVisualizations();
+ }, []);
+
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap b/dashboards-observability/public/components/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap
new file mode 100644
index 000000000..a98dbe783
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/__tests__/__snapshots__/data_grid.test.tsx.snap
@@ -0,0 +1,667 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Datagrid component Renders data grid component 1`] = `
+
+
+
+
+
+
+
+ double_per_ip_bytes
+
+
+ host
+
+
+ ip_count
+
+
+ per_ip_bytes
+
+
+ resp_code
+
+
+ sum_bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/__tests__/__snapshots__/no_results.test.tsx.snap b/dashboards-observability/public/components/explorer/__tests__/__snapshots__/no_results.test.tsx.snap
new file mode 100644
index 000000000..e7e97a213
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/__tests__/__snapshots__/no_results.test.tsx.snap
@@ -0,0 +1,211 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`No result component Renders No result component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+ No results match your search criteria
+
+
+
+
+
+
+
+
+
+
+
+
+ Expand your time range or modify your query
+
+
+
+
+ Your query may not match anything in the current time range, or there may not be any data at all in the currently selected time range. Try change time range, query filters or choose different time fields
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/__tests__/data_grid.test.tsx b/dashboards-observability/public/components/explorer/__tests__/data_grid.test.tsx
new file mode 100644
index 000000000..a45d7ecd9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/__tests__/data_grid.test.tsx
@@ -0,0 +1,48 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { DataGrid } from '../data_grid';
+import {
+ SELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ UNSELECTED_FIELDS,
+ QUERIED_FIELDS
+} from '../../../../common/constants/explorer';
+import {
+ AVAILABLE_FIELDS as SIDEBAR_AVAILABLE_FIELDS,
+ QUERY_FIELDS,
+ DATA_GRID_ROWS
+} from '../../../../test/event_analytics_constants';
+
+describe('Datagrid component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders data grid component', async () => {
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS,
+ [QUERIED_FIELDS]: QUERY_FIELDS
+ };
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/__tests__/explorer.test.tsx b/dashboards-observability/public/components/explorer/__tests__/explorer.test.tsx
new file mode 100644
index 000000000..29078fed1
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/__tests__/explorer.test.tsx
@@ -0,0 +1,54 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React, { MutableRefObject } from 'react';
+import { waitFor } from '@testing-library/react';
+import httpClientMock from '../../../../test/__mocks__/httpClientMock';
+// import { Explorer } from '../explorer';
+import PPLService from '../../../services/requests/ppl';
+import DSLService from '../../../services/requests/dsl';
+import SavedObjects from '../../../services/saved_objects/event_analytics/saved_objects';
+import TimestampUtils from '../../../services/timestamp/timestamp';
+import { coreStartMock } from '../../../../test/__mocks__/coreMocks';
+
+describe.skip('Event explorer component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders explorer component', async () => {
+ const pplService = new PPLService(httpClientMock);
+ const dslService = new DSLService(httpClientMock);
+ const tabId = 'query-panel-1';
+ const savedObjects = new SavedObjects(httpClientMock);
+ const timestampUtils = new TimestampUtils(dslService);
+ const setToast = jest.fn();
+ const history = jest.fn() as any;
+ history.replace = jest.fn();
+ history.push = jest.fn();
+ const notifications = coreStartMock.notifications;
+ const savedObjectId = 'JIcoln0BYMuJGDsOLTnM';
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/__tests__/no_results.test.tsx b/dashboards-observability/public/components/explorer/__tests__/no_results.test.tsx
new file mode 100644
index 000000000..b87c8dc13
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/__tests__/no_results.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { NoResults } from '../no_results';
+
+describe('No result component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders No result component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/data_grid.scss b/dashboards-observability/public/components/explorer/data_grid.scss
new file mode 100644
index 000000000..6de07488a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/data_grid.scss
@@ -0,0 +1,490 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * 1. Stack content vertically so the table can scroll when its constrained by a fixed container height.
+ */
+ doc-table {
+ @include euiScrollBar;
+ overflow: auto;
+ flex: 1 1 100%;
+ flex-direction: column; /* 1 */
+
+ .spinner {
+ position: absolute;
+ top: 40%;
+ left: 0;
+ right: 0;
+ z-index: $euiZLevel1;
+ opacity: 0.5;
+ }
+}
+
+.osdDocTable__container.loading {
+ opacity: 0.5;
+}
+
+.osdDocTable {
+ font-size: $euiFontSizeXS;
+
+ th {
+ white-space: nowrap;
+ padding-right: $euiSizeS;
+
+ .fa {
+ font-size: 1.1em;
+ }
+ }
+}
+
+.osd-table,
+.osdDocTable {
+ /**
+ * Style OpenSearch document _source in table view key: value
+ * Use alpha so this will stand out against non-white backgrounds, e.g. the highlighted
+ * row in the Context Log.
+ */
+
+ dl.source {
+ margin-bottom: 0;
+ line-height: 2em;
+ word-break: break-word;
+
+ dt,
+ dd {
+ display: inline;
+ }
+
+ dt {
+ background-color: transparentize(shade($euiColorPrimary, 20%), 0.9);
+ color: $euiTextColor;
+ padding: ($euiSizeXS / 2) $euiSizeXS;
+ margin-right: $euiSizeXS;
+ word-break: normal;
+ border-radius: $euiBorderRadius;
+ }
+ }
+}
+
+.osdDocTable__row {
+ td {
+ position: relative;
+
+ &:hover {
+ .osdDocTableRowFilterButton {
+ opacity: 1;
+ }
+ }
+ }
+}
+
+.osdDocTable__row--highlight {
+ td,
+ .osdDocTableRowFilterButton {
+ background-color: tintOrShade($euiColorPrimary, 90%, 70%);
+ }
+}
+
+.osdDocTable__bar {
+ margin: $euiSizeXS $euiSizeXS 0;
+}
+
+.osdDocTable__bar--footer {
+ position: relative;
+ margin: -($euiSize * 3) $euiSizeXS 0;
+}
+
+.osdDocTable__padBottom {
+ padding-bottom: $euiSizeXL;
+}
+
+.osdDocTable__error {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ flex: 1 0 100%;
+ text-align: center;
+}
+
+.truncate-by-height {
+ overflow: hidden;
+}
+
+.table {
+ // Nesting
+ .table {
+ background-color: $euiColorEmptyShade;
+ }
+}
+
+.osd-table {
+ // sub tables should not have a leading border
+ .table .table {
+ margin-bottom: 0;
+
+ tr:first-child > td {
+ border-top: none;
+ }
+
+ td.field-name {
+ font-weight: $euiFontWeightBold;
+ }
+ }
+
+ th {
+ text-align: left;
+ font-weight: bold;
+ }
+}
+
+table {
+ th {
+ i.fa-sort {
+ color: $euiColorLightShade;
+ }
+
+ button.fa-sort-asc,
+ button.fa-sort-down,
+ i.fa-sort-asc,
+ i.fa-sort-down {
+ color: $euiColorPrimary;
+ }
+
+ button.fa-sort-desc,
+ button.fa-sort-up,
+ i.fa-sort-desc,
+ i.fa-sort-up {
+ color: $euiColorPrimary;
+ }
+ }
+}
+
+/* ------------- table cell ---------- */
+.osdDocTableCell__dataField {
+ white-space: pre-wrap;
+}
+
+.osdDocTableCell__toggleDetails {
+ padding: 4px 0 0 0!important;
+}
+
+.osdDocTableCell__filter {
+ position: absolute;
+ white-space: nowrap;
+ right: 0;
+}
+
+/**
+ * 1. Align icon with text in cell.
+ * 2. Use opacity to make this element accessible to screen readers and keyboard.
+ * 3. Show on focus to enable keyboard accessibility.
+ */
+
+.osdDocTableRowFilterButton {
+ appearance: none;
+ background-color: $euiColorEmptyShade;
+ border: none;
+ padding: 0 $euiSizeXS;
+ font-size: $euiFontSizeS;
+ line-height: 1; /* 1 */
+ display: inline-block;
+ opacity: 0; /* 2 */
+
+ &:focus {
+ opacity: 1; /* 3 */
+ }
+}
+
+/* ------------- End of table cell ---------- */
+
+/* ------------- Discover like style -------- */
+.dscAppWrapper {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ overflow: hidden;
+}
+
+.dscAppContainer {
+ > * {
+ position: relative;
+ }
+}
+discover-app {
+ flex-grow: 1;
+}
+
+.dscHistogram {
+ display: flex;
+ height: 200px;
+ padding: $euiSizeS;
+}
+
+// SASSTODO: replace the z-index value with a variable
+.dscWrapper {
+ padding-left: $euiSizeXL;
+ padding-right: $euiSizeS;
+ margin-top: $euiSizeM;
+ z-index: 1;
+ @include euiBreakpoint('xs', 's', 'm') {
+ padding-left: $euiSizeS;
+ }
+}
+
+@include euiPanel('.dscWrapper__content');
+
+.dscWrapper__content {
+ padding-top: $euiSizeXS;
+ background-color: $euiColorEmptyShade;
+
+ .osd-table {
+ margin-bottom: 0;
+ }
+}
+
+.dscTimechart {
+ display: block;
+ position: relative;
+
+ // SASSTODO: the visualizing component should have an option or a modifier
+ .series > rect {
+ fill-opacity: 0.5;
+ stroke-width: 1;
+ }
+}
+
+.dscResultCount {
+ padding-top: $euiSizeXS;
+}
+
+.dscTimechart__header {
+ display: flex;
+ justify-content: center;
+ min-height: $euiSizeXXL;
+ padding: $euiSizeXS 0;
+}
+
+.dscOverlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 20;
+ padding-top: $euiSizeM;
+
+ opacity: 0.75;
+ text-align: center;
+ background-color: transparent;
+}
+
+.dscTable {
+ overflow: auto;
+
+ // SASSTODO: add a monospace modifier to the doc-table component
+ .osdDocTable__row {
+ font-family: $euiCodeFontFamily;
+ font-size: $euiFontSizeXS;
+ }
+}
+
+// SASSTODO: replace the padding value with a variable
+.dscTable__footer {
+ background-color: $euiColorLightShade;
+ padding: 5px 10px;
+ text-align: center;
+}
+
+.dscResults {
+ h3 {
+ margin: -20px 0 10px 0;
+ text-align: center;
+ }
+}
+
+.dscResults__interval {
+ display: inline-block;
+ width: auto;
+}
+
+.dscSkipButton {
+ position: absolute;
+ right: $euiSizeM;
+ top: $euiSizeXS;
+}
+
+.dscTableFixedScroll {
+ overflow-x: auto;
+ padding-bottom: 0;
+
+ + .dscTableFixedScroll__scroller {
+ position: fixed;
+ bottom: 0;
+ overflow-x: auto;
+ overflow-y: hidden;
+ }
+}
+
+.dscCollapsibleSidebar {
+ position: relative;
+ z-index: 1;
+
+ .dscCollapsibleSidebar__collapseButton {
+ position: absolute;
+ top: 0;
+ right: -$euiSizeXL + 4;
+ cursor: pointer;
+ z-index: -1;
+ min-height: $euiSizeM;
+ min-width: $euiSizeM;
+ padding: $euiSizeXS * .5;
+ }
+
+ &.closed {
+ width: 0 !important;
+ border-right-width: 0;
+ border-left-width: 0;
+ .dscCollapsibleSidebar__collapseButton {
+ right: -$euiSizeL + 4;
+ }
+ }
+}
+
+@include euiBreakpoint('xs', 's', 'm') {
+ .dscCollapsibleSidebar {
+ &.closed {
+ display: none;
+ }
+
+ .dscCollapsibleSidebar__collapseButton {
+ display: none;
+ }
+ }
+}
+
+/* ------------- Detail table cell -------- */
+/**
+ * 1. Visually align the actions with the tabs. We can improve this by using flexbox instead, at a later point.
+ */
+ .osdDocTableDetails__actions {
+ float: right;
+ padding-top: $euiSizeS; /* 1 */
+}
+
+// Overwrite the border on the bootstrap table
+.osdDocTableDetails__row {
+
+ > td {
+ // Offsets negative margins from an inner flex group
+ padding: $euiSizeL !important;
+
+ tr:hover td {
+ background: tintOrShade($euiColorLightestShade, 50%, 20%);
+ }
+ }
+
+ td {
+ border-top: none !important;
+ }
+}
+
+/* ------------- open -------- */
+.osdDocTableOpen__button {
+ appearance: none;
+ background-color: transparent;
+ padding: 0;
+ border: none;
+ width: 14px; /* 1 */
+ height: 14px;
+}
+
+/* ------------- table header -------- */
+.osdDocTableHeader {
+ white-space: nowrap;
+}
+.osdDocTableHeader button {
+ margin-left: $euiSizeXS;
+}
+.osdDocTableHeader__move,
+.osdDocTableHeader__sortChange {
+ opacity: 0;
+ th:hover &,
+ &:focus {
+ opacity: 1;
+ }
+}
+
+/* ------------- doc_viewer -------- */
+.osdDocViewerTable {
+ margin-top: $euiSizeS;
+}
+
+.osdDocViewer {
+ pre,
+ .osdDocViewer__value {
+ display: inline-block;
+ word-break: break-all;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ color: $euiColorFullShade;
+ vertical-align: top;
+ padding-top: 2px;
+ }
+ .osdDocViewer__field {
+ padding-top: 8px;
+ }
+
+ .dscFieldName {
+ color: $euiColorDarkShade;
+ }
+
+ td,
+ pre {
+ font-family: $euiCodeFontFamily;
+ }
+
+ tr:first-child td {
+ border-top-color: transparent;
+ }
+
+ tr:hover {
+ .osdDocViewer__actionButton {
+ opacity: 1;
+ }
+ }
+}
+
+.osdDocViewer__buttons,
+.osdDocViewer__field {
+ white-space: nowrap;
+}
+.osdDocViewer__buttons {
+ width: 60px;
+
+ // Show all icons if one is focused,
+ // IE doesn't support, but the fallback is just the focused button becomes visible
+ &:focus-within {
+ .osdDocViewer__actionButton {
+ opacity: 1;
+ }
+ }
+}
+
+.osdDocViewer__field {
+ width: 160px;
+}
+
+.osdDocViewer__actionButton {
+ opacity: 0;
+
+ &:focus {
+ opacity: 1;
+ }
+}
+
+.osdDocViewer__warning {
+ margin-right: $euiSizeS;
+}
+
diff --git a/dashboards-observability/public/components/explorer/data_grid.tsx b/dashboards-observability/public/components/explorer/data_grid.tsx
new file mode 100644
index 000000000..ad31d3745
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/data_grid.tsx
@@ -0,0 +1,152 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './data_grid.scss';
+
+import React, { useMemo, useState, useEffect, useRef, RefObject } from 'react';
+import { IExplorerFields } from '../../../common/types/explorer';
+import { DEFAULT_COLUMNS, PAGE_SIZE } from '../../../common/constants/explorer';
+import { getHeaders, getTrs, populateDataGrid } from './utils';
+import { HttpSetup } from '../../../../../src/core/public';
+import PPLService from '../../services/requests/ppl';
+
+interface DataGridProps {
+ http: HttpSetup;
+ pplService: PPLService;
+ rows: Array;
+ rowsAll: Array;
+ explorerFields: IExplorerFields;
+ timeStampField: string;
+ rawQuery: string;
+}
+
+export function DataGrid(props: DataGridProps) {
+ const { http, pplService, rows, rowsAll, explorerFields, timeStampField, rawQuery } = props;
+ const [limit, setLimit] = useState(PAGE_SIZE);
+ const loader = useRef(null);
+ const [rowRefs, setRowRefs] = useState[]>([]);
+
+ useEffect(() => {
+ if (!loader.current) return;
+
+ const observer = new IntersectionObserver(
+ (entries) => {
+ if (entries[0].isIntersecting) setLimit((limit) => limit + PAGE_SIZE);
+ },
+ {
+ root: null,
+ rootMargin: '500px',
+ threshold: 0,
+ }
+ );
+ observer.observe(loader.current);
+
+ return () => observer.disconnect();
+ }, [loader]);
+
+ const onFlyoutOpen = (docId: string) => {
+ rowRefs.forEach((rowRef) => {
+ rowRef.current?.closeAllFlyouts(docId);
+ });
+ };
+
+ const Queriedheaders = useMemo(() => getHeaders(explorerFields.queriedFields, DEFAULT_COLUMNS), [
+ explorerFields.queriedFields,
+ ]);
+ const [QueriedtableRows, setQueriedtableRows] = useState([]);
+ useEffect(() => {
+ setQueriedtableRows(
+ getTrs(
+ http,
+ explorerFields.queriedFields,
+ limit,
+ setLimit,
+ PAGE_SIZE,
+ timeStampField,
+ explorerFields,
+ pplService,
+ rawQuery,
+ rowRefs,
+ setRowRefs,
+ onFlyoutOpen,
+ rows
+ )
+ );
+ }, [rows, explorerFields.queriedFields]);
+
+ const headers = useMemo(() => getHeaders(explorerFields.selectedFields, DEFAULT_COLUMNS), [
+ explorerFields.selectedFields,
+ ]);
+ const [tableRows, setTableRows] = useState([]);
+ useEffect(() => {
+ const dataToRender =
+ explorerFields?.queriedFields && explorerFields.queriedFields.length > 0 ? rowsAll : rows;
+ setTableRows(
+ getTrs(
+ http,
+ explorerFields.selectedFields,
+ limit,
+ setLimit,
+ PAGE_SIZE,
+ timeStampField,
+ explorerFields,
+ pplService,
+ rawQuery,
+ rowRefs,
+ setRowRefs,
+ onFlyoutOpen,
+ dataToRender
+ )
+ );
+ }, [rows, explorerFields.selectedFields]);
+
+ useEffect(() => {
+ setQueriedtableRows((prev) =>
+ getTrs(
+ http,
+ explorerFields.queriedFields,
+ limit,
+ setLimit,
+ PAGE_SIZE,
+ timeStampField,
+ explorerFields,
+ pplService,
+ rawQuery,
+ rowRefs,
+ setRowRefs,
+ onFlyoutOpen,
+ rows,
+ prev
+ )
+ );
+ const dataToRender =
+ explorerFields?.queriedFields && explorerFields.queriedFields.length > 0 ? rowsAll : rows;
+ setTableRows((prev) =>
+ getTrs(
+ http,
+ explorerFields.selectedFields,
+ limit,
+ setLimit,
+ PAGE_SIZE,
+ timeStampField,
+ explorerFields,
+ pplService,
+ rawQuery,
+ rowRefs,
+ setRowRefs,
+ onFlyoutOpen,
+ dataToRender,
+ prev
+ )
+ );
+ }, [limit]);
+
+ return (
+ <>
+ {populateDataGrid(explorerFields, Queriedheaders, QueriedtableRows, headers, tableRows)}
+
+ >
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewer.test.tsx.snap b/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewer.test.tsx.snap
new file mode 100644
index 000000000..00693159c
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewer.test.tsx.snap
@@ -0,0 +1,421 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Datagrid Doc viewer component Renders Doc viewer component 1`] = `
+
+
+
+
+
+
+
+
+
+ ,
+ "id": "doc_viewer_tab_2",
+ "name": "Table",
+ }
+ }
+ tabs={
+ Array [
+ Object {
+ "content":
+
+
+
+
+
+
+ ,
+ "id": "doc_viewer_tab_2",
+ "name": "Table",
+ },
+ Object {
+ "content":
+
+
+
+
+
+
+ ,
+ "id": "doc_viewer_tab_3",
+ "name": "JSON",
+ },
+ Object {
+ "content":
+
+
+
+
+
+
+ ,
+ "id": "doc_viewer_tab_4",
+ "name":
+
+ Traces
+
+
+ ,
+ },
+ ]
+ }
+ >
+
+
+
+
+
+
+ Table
+
+
+
+
+
+
+ JSON
+
+
+
+
+
+
+
+ Traces
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ avg(FlightDelayMin)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Carrier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewerRow.test.tsx.snap b/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewerRow.test.tsx.snap
new file mode 100644
index 000000000..b023ef06d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/__tests__/__snapshots__/docViewerRow.test.tsx.snap
@@ -0,0 +1,64 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Datagrid Doc viewer row component Renders Doc viewer row component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+ 45.957544288332315
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/docTable/__tests__/docViewer.test.tsx b/dashboards-observability/public/components/explorer/docTable/__tests__/docViewer.test.tsx
new file mode 100644
index 000000000..3a807d7c9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/__tests__/docViewer.test.tsx
@@ -0,0 +1,34 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { DocViewer } from '../docViewer';
+
+describe('Datagrid Doc viewer component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders Doc viewer component', async () => {
+
+ const hit = {
+ 'Carrier': 'JetBeats',
+ 'avg(FlightDelayMin)': '45.957544288332315'
+ };
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/docTable/__tests__/docViewerRow.test.tsx b/dashboards-observability/public/components/explorer/docTable/__tests__/docViewerRow.test.tsx
new file mode 100644
index 000000000..684ede48c
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/__tests__/docViewerRow.test.tsx
@@ -0,0 +1,39 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { DocViewRow } from '../docViewRow';
+
+describe('Datagrid Doc viewer row component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders Doc viewer row component', async () => {
+
+ const hit = {
+ 'Carrier': 'JetBeats',
+ 'avg(FlightDelayMin)': '45.957544288332315'
+ };
+ const selectedCols = [{
+ name: 'avg(FlightDelayMin)',
+ type: 'double'
+ }];
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTable.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTable.tsx
new file mode 100644
index 000000000..35c21917b
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTable.tsx
@@ -0,0 +1,93 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import { DocViewTableRow } from './table_row';
+
+export interface FieldMapping {
+ filterable?: boolean;
+ scripted?: boolean;
+ rowCount?: number;
+ type: string;
+ name: string;
+}
+
+export type DocViewFilterFn = (
+ mapping: FieldMapping | string | undefined,
+ value: unknown,
+ mode: '+' | '-'
+) => void;
+
+export interface DocViewRenderProps {
+ columns?: string[];
+ filter?: DocViewFilterFn;
+ hit: any;
+ onAddColumn?: (columnName: string) => void;
+ onRemoveColumn?: (columnName: string) => void;
+}
+
+const fieldType = 'string';
+const displayUnderscoreWarning = false;
+const displayNoMappingWarning = false;
+const isCollapsed = false;
+const isCollapsible = false;
+const isColumnActive = false;
+
+export function DocViewTable({
+ hit,
+ filter,
+ columns,
+ onAddColumn,
+ onRemoveColumn,
+}: DocViewRenderProps) {
+ const [fieldRowOpen, setFieldRowOpen] = useState({} as Record);
+
+ function toggleValueCollapse(field: string) {
+ fieldRowOpen[field] = fieldRowOpen[field] !== true;
+ setFieldRowOpen({ ...fieldRowOpen });
+ }
+
+ return (
+
+
+ {Object.keys(hit)
+ .sort((preKey, nextKey) => {
+ return preKey.toLowerCase().localeCompare(nextKey.toLowerCase());
+ })
+ .map((field) => {
+ const value = hit[field] === 'null' ? '' : hit[field];
+ const toggleColumn =
+ onRemoveColumn && onAddColumn && Array.isArray(columns)
+ ? () => {
+ if (columns.includes(field)) {
+ onRemoveColumn(field);
+ } else {
+ onAddColumn(field);
+ }
+ }
+ : undefined;
+
+ return (
+ toggleValueCollapse(field)}
+ onToggleColumn={toggleColumn}
+ value={value}
+ valueRaw={value}
+ />
+ );
+ })}
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTitle.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTitle.tsx
new file mode 100644
index 000000000..f3e0bb3bf
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/docDetailTitle.tsx
@@ -0,0 +1,55 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiIcon } from '@elastic/eui';
+
+export const DocDetailTitle : React.FC = (props) => {
+ return (
+
+
+
+
+
+
+
+
+ Expanded document
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.test.ts b/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.test.ts
new file mode 100644
index 000000000..b714d76c5
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.test.ts
@@ -0,0 +1,33 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { arrayContainsObjects } from './table_helper';
+
+describe('arrayContainsObjects', () => {
+ it(`returns false for an array of primitives`, () => {
+ const actual = arrayContainsObjects(['test', 'test']);
+ expect(actual).toBeFalsy();
+ });
+
+ it(`returns true for an array of objects`, () => {
+ const actual = arrayContainsObjects([{}, {}]);
+ expect(actual).toBeTruthy();
+ });
+
+ it(`returns true for an array of objects and primitves`, () => {
+ const actual = arrayContainsObjects([{}, 'sdf']);
+ expect(actual).toBeTruthy();
+ });
+
+ it(`returns false for an array of null values`, () => {
+ const actual = arrayContainsObjects([null, null]);
+ expect(actual).toBeFalsy();
+ });
+
+ it(`returns false if no array is given`, () => {
+ const actual = arrayContainsObjects([null, null]);
+ expect(actual).toBeFalsy();
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.tsx
new file mode 100644
index 000000000..b0b3229d0
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_helper.tsx
@@ -0,0 +1,18 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * Returns true if the given array contains at least 1 object
+ */
+export function arrayContainsObjects(value: unknown[]): boolean {
+ return Array.isArray(value) && value.some((v) => typeof v === 'object' && v !== null);
+}
+
+/**
+ * Removes markup added by kibana fields html formatter
+ */
+export function trimAngularSpan(text: string): string {
+ return text.replace(/^/, '').replace(/<\/span>$/, '');
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row.tsx
new file mode 100644
index 000000000..875c29191
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row.tsx
@@ -0,0 +1,118 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import classNames from 'classnames';
+import React, { ReactNode } from 'react';
+// import { FieldMapping, DocViewFilterFn } from '../../doc_views/doc_views_types';
+import { DocViewTableRowBtnFilterAdd } from './table_row_btn_filter_add';
+import { DocViewTableRowBtnFilterRemove } from './table_row_btn_filter_remove';
+import { DocViewTableRowBtnToggleColumn } from './table_row_btn_toggle_column';
+import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse';
+import { DocViewTableRowBtnFilterExists } from './table_row_btn_filter_exists';
+import { DocViewTableRowIconNoMapping } from './table_row_icon_no_mapping';
+import { DocViewTableRowIconUnderscore } from './table_row_icon_underscore';
+import { FieldName } from '../../../common/field_name/field_name';
+
+export interface FieldMapping {
+ filterable?: boolean;
+ scripted?: boolean;
+ rowCount?: number;
+ type: string;
+ name: string;
+}
+
+export type DocViewFilterFn = (
+ mapping: FieldMapping | string | undefined,
+ value: unknown,
+ mode: '+' | '-'
+) => void;
+
+export interface Props {
+ field: string;
+ fieldMapping?: FieldMapping;
+ fieldType: string;
+ displayNoMappingWarning: boolean;
+ displayUnderscoreWarning: boolean;
+ isCollapsible: boolean;
+ isColumnActive: boolean;
+ isCollapsed: boolean;
+ onToggleCollapse: () => void;
+ onFilter?: DocViewFilterFn;
+ onToggleColumn?: () => void;
+ value: string | ReactNode;
+ valueRaw: unknown;
+}
+
+export function DocViewTableRow({
+ field,
+ fieldMapping,
+ fieldType,
+ displayNoMappingWarning,
+ displayUnderscoreWarning,
+ isCollapsible,
+ isCollapsed,
+ isColumnActive,
+ onFilter,
+ onToggleCollapse,
+ onToggleColumn,
+ value,
+ valueRaw,
+}: Props) {
+ const valueClassName = classNames({
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ osdDocViewer__value: true,
+ 'truncate-by-height': isCollapsible && isCollapsed,
+ });
+
+ return (
+
+ {typeof onFilter === 'function' && (<>>
+ //
+ // onFilter(fieldMapping, valueRaw, '+')}
+ // />
+ // onFilter(fieldMapping, valueRaw, '-')}
+ // />
+ // {typeof onToggleColumn === 'function' && (
+ //
+ // )}
+ // onFilter('_exists_', field, '+')}
+ // scripted={fieldMapping && fieldMapping.scripted}
+ // />
+ //
+ )}
+
+
+
+
+ {isCollapsible && (
+
+ )}
+ {displayUnderscoreWarning && }
+ {displayNoMappingWarning && }
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_collapse.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_collapse.tsx
new file mode 100644
index 000000000..8a1caaaa0
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_collapse.tsx
@@ -0,0 +1,31 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { i18n } from '@osd/i18n';
+import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
+
+export interface Props {
+ onClick: () => void;
+ isCollapsed: boolean;
+}
+
+export function DocViewTableRowBtnCollapse({ onClick, isCollapsed }: Props) {
+ const label = i18n.translate('discover.docViews.table.toggleFieldDetails', {
+ defaultMessage: 'Toggle field details',
+ });
+ return (
+
+ onClick()}
+ iconType={isCollapsed ? 'arrowRight' : 'arrowDown'}
+ iconSize={'s'}
+ />
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_add.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_add.tsx
new file mode 100644
index 000000000..09a1944d9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_add.tsx
@@ -0,0 +1,44 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FormattedMessage } from '@osd/i18n/react';
+import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export interface Props {
+ onClick: () => void;
+ disabled: boolean;
+}
+
+export function DocViewTableRowBtnFilterAdd({ onClick, disabled = false }: Props) {
+ const tooltipContent = disabled ? (
+
+ ) : (
+
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_exists.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_exists.tsx
new file mode 100644
index 000000000..494aec4c1
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_exists.tsx
@@ -0,0 +1,56 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FormattedMessage } from '@osd/i18n/react';
+import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export interface Props {
+ onClick: () => void;
+ disabled?: boolean;
+ scripted?: boolean;
+}
+
+export function DocViewTableRowBtnFilterExists({
+ onClick,
+ disabled = false,
+ scripted = false,
+}: Props) {
+ const tooltipContent = disabled ? (
+ scripted ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_remove.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_remove.tsx
new file mode 100644
index 000000000..201fbf902
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_filter_remove.tsx
@@ -0,0 +1,44 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FormattedMessage } from '@osd/i18n/react';
+import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export interface Props {
+ onClick: () => void;
+ disabled?: boolean;
+}
+
+export function DocViewTableRowBtnFilterRemove({ onClick, disabled = false }: Props) {
+ const tooltipContent = disabled ? (
+
+ ) : (
+
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_toggle_column.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_toggle_column.tsx
new file mode 100644
index 000000000..f9cc8a1cf
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_btn_toggle_column.tsx
@@ -0,0 +1,54 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FormattedMessage } from '@osd/i18n/react';
+import { EuiToolTip, EuiButtonIcon } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export interface Props {
+ active: boolean;
+ disabled?: boolean;
+ onClick: () => void;
+}
+
+export function DocViewTableRowBtnToggleColumn({ onClick, active, disabled = false }: Props) {
+ if (disabled) {
+ return (
+
+ );
+ }
+ return (
+
+ }
+ >
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_no_mapping.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_no_mapping.tsx
new file mode 100644
index 000000000..5991c3079
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_no_mapping.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import React from 'react';
+import { EuiIconTip } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export function DocViewTableRowIconNoMapping() {
+ const ariaLabel = i18n.translate('discover.docViews.table.noCachedMappingForThisFieldAriaLabel', {
+ defaultMessage: 'Warning',
+ });
+ const tooltipContent = i18n.translate(
+ 'discover.docViews.table.noCachedMappingForThisFieldTooltip',
+ {
+ defaultMessage:
+ 'No cached mapping for this field. Refresh field list from the Management > Index Patterns page',
+ }
+ );
+ return (
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_underscore.tsx b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_underscore.tsx
new file mode 100644
index 000000000..f0bd9a5a6
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/detailTable/table_row_icon_underscore.tsx
@@ -0,0 +1,38 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiIconTip } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+
+export function DocViewTableRowIconUnderscore() {
+ const ariaLabel = i18n.translate(
+ 'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedAriaLabel',
+ {
+ defaultMessage: 'Warning',
+ }
+ );
+ const tooltipContent = i18n.translate(
+ 'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedTooltip',
+ {
+ defaultMessage: 'Field names beginning with {underscoreSign} are not supported',
+ values: { underscoreSign: '_' },
+ }
+ );
+
+ return (
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/docView.scss b/dashboards-observability/public/components/explorer/docTable/docView.scss
new file mode 100644
index 000000000..fbe69b2a6
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/docView.scss
@@ -0,0 +1,51 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.selected-event-row {
+ background-color: rgba(5, 143, 244, 0.1);
+}
+
+.doc-flyout table {
+ width: 100%;
+ display: inline-block;
+ overflow-x: scroll;
+}
+
+.doc-flyout td.eui-textNoWrap {
+ padding-top: 1.25vh;
+}
+
+.doc-flyout td {
+ vertical-align: top;
+ padding: 0.5vh;
+}
+
+.compare-checkbox {
+ padding: 8px;
+}
+
+.header-button {
+ margin-right: 55px;
+}
+
+.cnt-picker {
+ width: 80px;
+ text-align: center;
+}
+
+.events-flyout-resize {
+ position: absolute;
+ right: 50px;
+ top: 17px;
+ z-index: 3;
+}
+
+.vertical-center {
+ margin-top: auto;
+}
+
+.trace-link {
+ margin-left: 5px;
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/docViewRow.tsx b/dashboards-observability/public/components/explorer/docTable/docViewRow.tsx
new file mode 100644
index 000000000..06a6bb3a1
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/docViewRow.tsx
@@ -0,0 +1,284 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './docView.scss';
+import moment from 'moment';
+import React, { forwardRef, useImperativeHandle, useMemo, useState } from 'react';
+import { toPairs, uniqueId, has, forEach, isEqual } from 'lodash';
+import { EuiIcon, EuiLink } from '@elastic/eui';
+import { useEffect } from 'react';
+import { IExplorerFields, IField } from '../../../../common/types/explorer';
+import { DocFlyout } from './doc_flyout';
+import { HttpStart } from '../../../../../../src/core/public';
+import { OTEL_TRACE_ID, DATE_PICKER_FORMAT } from '../../../../common/constants/explorer';
+import { SurroundingFlyout } from './surrounding_flyout';
+import PPLService from '../../../services/requests/ppl';
+import { isValidTraceId } from '../utils';
+
+export interface IDocType {
+ [key: string]: string;
+}
+
+interface IDocViewRowProps {
+ http: HttpStart;
+ doc: IDocType;
+ docId: string;
+ selectedCols: IField[];
+ timeStampField: string;
+ explorerFields: IExplorerFields;
+ pplService: PPLService;
+ rawQuery: string;
+ onFlyoutOpen: (docId: string) => void;
+}
+
+export const DocViewRow = forwardRef((props: IDocViewRowProps, ref) => {
+ const {
+ http,
+ doc,
+ docId,
+ selectedCols,
+ timeStampField,
+ explorerFields,
+ pplService,
+ rawQuery,
+ onFlyoutOpen,
+ } = props;
+
+ const [detailsOpen, setDetailsOpen] = useState(false);
+ const [surroundingEventsOpen, setSurroundingEventsOpen] = useState(false);
+ const [openTraces, setOpenTraces] = useState(false);
+ const [flyoutToggleSize, setFlyoutToggleSize] = useState(true);
+
+ useImperativeHandle(ref, () => ({
+ closeAllFlyouts(openDocId: string) {
+ if (openDocId !== docId && (detailsOpen || surroundingEventsOpen)) {
+ setSurroundingEventsOpen(false);
+ setDetailsOpen(false);
+ }
+ },
+ }));
+
+ const getTdTmpl = (conf: { clsName: string; content: React.ReactDOM | string }) => {
+ const { clsName, content } = conf;
+ return (
+
+ {typeof content === 'boolean' ? String(content) : content}
+
+ );
+ };
+
+ const getDlTmpl = (conf: { doc: IDocType }, isFlyout: boolean) => {
+ const { doc } = conf;
+
+ return (
+
+
+
+ {toPairs(doc).map((entry: string[]) => {
+ const isTraceField = entry[0] === OTEL_TRACE_ID;
+ return (
+
+ {entry[0]}:
+
+
+ {isTraceField && isValidTraceId(entry[1]) && !isFlyout ? (
+ {entry[1]}
+ ) : (
+ entry[1]
+ )}
+
+
+
+ );
+ })}
+
+
+
+ );
+ };
+
+ const tracesFlyout = () => {
+ setOpenTraces(true);
+ if (!detailsOpen) toggleDetailOpen();
+ };
+
+ const getDiscoverSourceLikeDOM = (doc: IDocType, isFlyout: boolean) => {
+ return getDlTmpl({ doc }, isFlyout);
+ };
+
+ const toggleDetailOpen = () => {
+ if (surroundingEventsOpen) {
+ setSurroundingEventsOpen(false);
+ setDetailsOpen(false);
+ } else {
+ const newState = !detailsOpen;
+ setDetailsOpen(newState);
+ }
+ };
+
+ const getExpColapTd = () => {
+ return (
+
+ {
+ toggleDetailOpen();
+ }}
+ >
+ {detailsOpen || surroundingEventsOpen ? (
+
+ ) : (
+
+ )}
+
+
+ );
+ };
+
+ const getTds = (doc: IDocType, selectedCols: IField[], isFlyout: boolean) => {
+ const cols = [];
+ const fieldClsName = 'osdDocTableCell__dataField eui-textBreakAll eui-textBreakWord';
+ const timestampClsName = 'eui-textNoWrap';
+ // No field is selected
+ if (!selectedCols || selectedCols.length === 0) {
+ if (has(doc, timeStampField)) {
+ cols.push(
+ getTdTmpl({
+ clsName: timestampClsName,
+ content: moment.utc(doc[timeStampField]).local().format(DATE_PICKER_FORMAT),
+ })
+ );
+ }
+ const _sourceLikeDOM = getDiscoverSourceLikeDOM(doc, isFlyout);
+ cols.push(
+ getTdTmpl({
+ clsName: fieldClsName,
+ content: _sourceLikeDOM,
+ })
+ );
+ } else {
+ // Has at least one field selected
+ const filteredDoc = {};
+ forEach(selectedCols, (selCol) => {
+ if (has(doc, selCol.name)) {
+ filteredDoc[selCol.name] = doc[selCol.name];
+ }
+ });
+ forEach(filteredDoc, (val, key) => {
+ cols.push(
+ getTdTmpl({
+ clsName: fieldClsName,
+ content: isEqual(key, timeStampField)
+ ? moment.utc(val).local().format(DATE_PICKER_FORMAT)
+ : val,
+ })
+ );
+ });
+ }
+
+ // Add detail toggling column
+ cols.unshift(getExpColapTd());
+ return cols;
+ };
+
+ const memorizedTds = useMemo(() => {
+ return getTds(doc, selectedCols, false);
+ }, [doc, selectedCols, detailsOpen, surroundingEventsOpen]);
+
+ const memorizedDocFlyout = useMemo(() => {
+ return (
+
+ );
+ }, [
+ http,
+ detailsOpen,
+ doc,
+ timeStampField,
+ selectedCols,
+ explorerFields,
+ openTraces,
+ rawQuery,
+ flyoutToggleSize,
+ ]);
+
+ const memorizedSurroundingFlyout = useMemo(() => {
+ return (
+
+ );
+ }, [
+ http,
+ detailsOpen,
+ doc,
+ timeStampField,
+ selectedCols,
+ explorerFields,
+ openTraces,
+ pplService,
+ rawQuery,
+ selectedCols,
+ flyoutToggleSize,
+ ]);
+
+ let flyout;
+ if (detailsOpen) {
+ flyout = memorizedDocFlyout;
+ }
+
+ if (surroundingEventsOpen) {
+ flyout = memorizedSurroundingFlyout;
+ }
+
+ useEffect(() => {
+ if (detailsOpen) {
+ onFlyoutOpen(docId);
+ }
+ }, [detailsOpen]);
+
+ return (
+ <>
+
+ {memorizedTds}
+
+ {flyout}
+ >
+ );
+});
diff --git a/dashboards-observability/public/components/explorer/docTable/docViewer.tsx b/dashboards-observability/public/components/explorer/docTable/docViewer.tsx
new file mode 100644
index 000000000..240e7fdce
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/docViewer.tsx
@@ -0,0 +1,121 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useEffect, useMemo, useState } from 'react';
+import _ from 'lodash';
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLink,
+ EuiPanel,
+ EuiTabbedContent,
+ EuiTabbedContentTab,
+} from '@elastic/eui';
+import { DocViewTable } from './detailTable/docDetailTable';
+import { JsonCodeBlock } from './json_code_block/json_code_block';
+import { IDocType } from './docViewRow';
+import { HttpSetup } from '../../../../../../src/core/public';
+import { TraceBlock } from './trace_block/trace_block';
+import { OTEL_TRACE_ID } from '../../../../common/constants/explorer';
+import { isValidTraceId } from '../utils';
+
+interface IDocViewerProps {
+ http: HttpSetup;
+ hit: IDocType;
+ openTraces: boolean;
+}
+
+export function DocViewer(props: IDocViewerProps) {
+ const [curSelectedTab, setCurSelectedTab] = useState(null);
+ const [logTraceId, setLogTraceId] = useState('');
+ const [tracesLink, setTracesLink] = useState(<>>);
+
+ // can be passed in later
+ const getTabList = () => {
+ return [
+ {
+ id: _.uniqueId('doc_viewer_tab_'),
+ name: 'Table',
+ component: (tabProps: any) => (
+ {}}
+ onAddColumn={() => {}}
+ onRemoveColumn={() => {}}
+ {...tabProps}
+ />
+ ),
+ otherProps: {},
+ },
+ {
+ id: _.uniqueId('doc_viewer_tab_'),
+ name: 'JSON',
+ component: (tabProps: any) => ,
+ otherProps: {},
+ },
+ {
+ id: _.uniqueId('doc_viewer_tab_'),
+ name: (
+ <>
+ Traces
+ {tracesLink}
+ >
+ ),
+
+ component: (tabProps: any) => ,
+ otherProps: {},
+ },
+ ];
+ };
+
+ const tabs = useMemo(() => {
+ return getTabList().map((tab) => {
+ const Component = tab.component;
+ return {
+ id: tab.id,
+ name: tab.name,
+
+ content: (
+
+
+
+ {' '}
+
+
+
+ ),
+ };
+ });
+ }, [props.hit, logTraceId, tracesLink]);
+
+ if (!tabs.length) {
+ // There there's a minimum of 2 tabs active in Discover.
+ // This condition takes care of unit tests with 0 tabs.
+ return null;
+ }
+
+ useEffect(() => {
+ const traceId = props.hit.hasOwnProperty(OTEL_TRACE_ID) ? props.hit[OTEL_TRACE_ID] : '';
+ setLogTraceId(traceId);
+ if (traceId !== '' && isValidTraceId(traceId))
+ setTracesLink(
+
+ );
+ }, []);
+
+ return (
+
+ setCurSelectedTab(selectedTab)}
+ />
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/doc_flyout.tsx b/dashboards-observability/public/components/explorer/docTable/doc_flyout.tsx
new file mode 100644
index 000000000..fdff39ea3
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/doc_flyout.tsx
@@ -0,0 +1,149 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './docView.scss';
+import React from 'react';
+import {
+ EuiButton,
+ EuiButtonIcon,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFlyoutBody,
+ EuiFlyoutHeader,
+ EuiTitle,
+ EuiToolTip,
+} from '@elastic/eui';
+import moment from 'moment';
+import { FlyoutContainers } from '../../common/flyout_containers';
+import { IDocType } from './docViewRow';
+import { DocViewer } from './docViewer';
+import { uiSettingsService } from '../../../../common/utils';
+import { IExplorerFields } from '../../../../common/types/explorer';
+import { getHeaders, populateDataGrid } from '../utils';
+import { DEFAULT_COLUMNS } from '../../../../common/constants/explorer';
+import { HttpSetup } from '../../../../../../src/core/public';
+import { PPL_STATS_REGEX } from '../../../../common/constants/shared';
+
+interface Props {
+ http: HttpSetup;
+ detailsOpen: boolean;
+ setDetailsOpen: React.Dispatch>;
+ doc: IDocType;
+ timeStampField: string;
+ memorizedTds: JSX.Element[];
+ explorerFields: IExplorerFields;
+ openTraces: boolean;
+ rawQuery: string;
+ toggleSize: boolean;
+ setToggleSize: React.Dispatch>;
+ setOpenTraces: React.Dispatch>;
+ setSurroundingEventsOpen: React.Dispatch>;
+}
+
+export const DocFlyout = ({
+ http,
+ detailsOpen,
+ setDetailsOpen,
+ doc,
+ timeStampField,
+ memorizedTds,
+ explorerFields,
+ openTraces,
+ rawQuery,
+ toggleSize,
+ setToggleSize,
+ setOpenTraces,
+ setSurroundingEventsOpen,
+}: Props) => {
+ const closeFlyout = () => {
+ setDetailsOpen(false);
+ setOpenTraces(false);
+ };
+
+ const openSurroundingFlyout = () => {
+ setSurroundingEventsOpen(true);
+ closeFlyout();
+ };
+
+ const flyoutHeader = (
+
+
+
+
+
+ {doc.hasOwnProperty(timeStampField)
+ ? `Event: ${moment(doc[timeStampField]).format(
+ uiSettingsService.get('dateFormat')
+ )}`
+ : `Event Details`}
+
+
+
+
+ {
+ setToggleSize((isOn) => !isOn);
+ }}
+ />
+
+
+ Cannot view surrounding events with `stats` command in PPL query
+ ) : !doc.hasOwnProperty(timeStampField) ? (
+ Cannot view surrounding events without time field in query response
+ ) : (
+ View surrounding events based on timestamp
+ )
+ }
+ >
+
+ View surrounding events
+
+
+
+
+
+ );
+
+ const flyoutBody = (
+
+ {populateDataGrid(
+ explorerFields,
+ getHeaders(explorerFields.queriedFields, DEFAULT_COLUMNS.slice(1), true),
+ {memorizedTds} ,
+ getHeaders(explorerFields.selectedFields, DEFAULT_COLUMNS.slice(1), true),
+ {memorizedTds}
+ )}
+
+
+ );
+
+ const flyoutFooter = <>>;
+
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/docTable/index.ts b/dashboards-observability/public/components/explorer/docTable/index.ts
new file mode 100644
index 000000000..13b7318fa
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './docViewer';
+export * from './docViewRow';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/__snapshots__/json_code_block.test.tsx.snap b/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/__snapshots__/json_code_block.test.tsx.snap
new file mode 100644
index 000000000..fd63e4c24
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/__snapshots__/json_code_block.test.tsx.snap
@@ -0,0 +1,142 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Doc viewer JSON block component Renders JSON block component 1`] = `
+
+
+
+
+ {
+ "Carrier": "JetBeats",
+ "avg(FlightDelayMin)": "45.957544288332315"
+}
+
+ }
+ >
+ {
+ "Carrier": "JetBeats",
+ "avg(FlightDelayMin)": "45.957544288332315"
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/json_code_block.test.tsx b/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/json_code_block.test.tsx
new file mode 100644
index 000000000..c79a7611f
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/json_code_block/__tests__/json_code_block.test.tsx
@@ -0,0 +1,34 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { JsonCodeBlock } from '../json_code_block';
+
+describe('Doc viewer JSON block component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders JSON block component', async () => {
+
+ const hit = {
+ 'Carrier': 'JetBeats',
+ 'avg(FlightDelayMin)': '45.957544288332315'
+ };
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/docTable/json_code_block/json_code_block.tsx b/dashboards-observability/public/components/explorer/docTable/json_code_block/json_code_block.tsx
new file mode 100644
index 000000000..a687cdb49
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/json_code_block/json_code_block.tsx
@@ -0,0 +1,20 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiCodeBlock } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+import { IDocType } from '../docViewRow';
+
+export function JsonCodeBlock({ hit }: { hit: IDocType }) {
+ const label = i18n.translate('discover.docViews.json.codeEditorAriaLabel', {
+ defaultMessage: 'Read only JSON view of an elasticsearch document',
+ });
+ return (
+
+ {JSON.stringify(hit, null, 2)}
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/docTable/surrounding_flyout.tsx b/dashboards-observability/public/components/explorer/docTable/surrounding_flyout.tsx
new file mode 100644
index 000000000..5ca0701dc
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/surrounding_flyout.tsx
@@ -0,0 +1,279 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './docView.scss';
+import React, { useEffect, useState } from 'react';
+import {
+ EuiButton,
+ EuiButtonEmpty,
+ EuiButtonIcon,
+ EuiCallOut,
+ EuiFieldNumber,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFlyoutBody,
+ EuiFlyoutHeader,
+ EuiFormRow,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+ EuiToolTip,
+} from '@elastic/eui';
+import { FlyoutContainers } from '../../common/flyout_containers';
+import { IDocType } from './docViewRow';
+import { IExplorerFields, IField } from '../../../../common/types/explorer';
+import { getHeaders, fetchSurroundingData, rangeNumDocs, populateDataGrid } from '../utils';
+import { DEFAULT_COLUMNS } from '../../../../common/constants/explorer';
+import { HttpSetup } from '../../../../../../src/core/public';
+import PPLService from '../../../services/requests/ppl';
+
+interface Props {
+ http: HttpSetup;
+ detailsOpen: boolean;
+ setDetailsOpen: React.Dispatch>;
+ doc: IDocType;
+ timeStampField: string;
+ memorizedTds: JSX.Element[];
+ explorerFields: IExplorerFields;
+ openTraces: boolean;
+ setOpenTraces: React.Dispatch>;
+ setSurroundingEventsOpen: React.Dispatch>;
+ pplService: PPLService;
+ rawQuery: string;
+ selectedCols: IField[];
+ getTds: (doc: IDocType, selectedCols: IField[], isFlyout: boolean) => JSX.Element[];
+ toggleSize: boolean;
+ setToggleSize: React.Dispatch>;
+}
+
+export const SurroundingFlyout = ({
+ http,
+ detailsOpen,
+ setDetailsOpen,
+ doc,
+ timeStampField,
+ memorizedTds,
+ explorerFields,
+ openTraces,
+ setOpenTraces,
+ setSurroundingEventsOpen,
+ pplService,
+ rawQuery,
+ selectedCols,
+ getTds,
+ toggleSize,
+ setToggleSize,
+}: Props) => {
+ const [numNewEvents, setNumNewEvents] = useState(5);
+ const [valueOldEvents, setNumOldEvents] = useState(5);
+ const [loadingNewEvents, setLoadingNewEvents] = useState(false);
+ const [loadingOldEvents, setLoadingOldEvents] = useState(false);
+ const [oldEventsError, setOldEventsError] = useState('');
+ const [newEventsError, setNewEventsError] = useState('');
+ const [newEventsData, setNewEventsData] = useState([[]]);
+ const [oldEventsData, setOldEventsData] = useState([[]]);
+
+ const closeFlyout = () => {
+ setDetailsOpen(false);
+ setOpenTraces(false);
+ setSurroundingEventsOpen(false);
+ };
+
+ const openDetailsFlyout = () => {
+ setDetailsOpen(true);
+ setOpenTraces(false);
+ setSurroundingEventsOpen(false);
+ };
+
+ const loadData = async (typeOfDocs: 'new' | 'old', value: number) => {
+ const numDocs = rangeNumDocs(value);
+ let resultCount = 0;
+ if (typeOfDocs === 'new') {
+ resultCount = await fetchSurroundingData(
+ pplService,
+ rawQuery,
+ timeStampField,
+ doc[timeStampField],
+ numDocs,
+ 'new',
+ setNewEventsData,
+ setNewEventsError,
+ setLoadingNewEvents,
+ selectedCols,
+ getTds
+ );
+ setNumNewEvents(resultCount);
+ } else {
+ resultCount = await fetchSurroundingData(
+ pplService,
+ rawQuery,
+ timeStampField,
+ doc[timeStampField],
+ numDocs,
+ 'old',
+ setOldEventsData,
+ setOldEventsError,
+ setLoadingOldEvents,
+ selectedCols,
+ getTds
+ );
+ setNumOldEvents(resultCount);
+ }
+ };
+
+ const loadButton = (typeOfDocs: 'new' | 'old') => {
+ typeOfDocs === 'new'
+ ? loadData(typeOfDocs, numNewEvents + 5)
+ : loadData(typeOfDocs, valueOldEvents + 5);
+ };
+
+ const handleKeyDown = (
+ event: React.KeyboardEvent,
+ typeOfDocs: 'new' | 'old'
+ ) => {
+ if (event.key === 'Enter') {
+ loadData(typeOfDocs, typeOfDocs === 'new' ? numNewEvents : valueOldEvents);
+ }
+ };
+
+ const onChangeNewEvents = (e: React.ChangeEvent) => {
+ setNumNewEvents(parseInt(e.target.value));
+ };
+
+ const onChangeOldEvents = (e: React.ChangeEvent) => {
+ setNumOldEvents(parseInt(e.target.value));
+ };
+
+ const flyoutHeader = (
+
+
+
+
+
+ View surrounding events
+
+
+
+
+ {
+ setToggleSize((isOn) => !isOn);
+ }}
+ />
+
+
+
+ View event details
+
+
+
+
+ );
+
+ const getInputForm = (
+ iconType: string,
+ onChange: React.ChangeEventHandler,
+ value: number,
+ typeOfDocs: 'new' | 'old'
+ ) => {
+ return (
+
+
+
+ loadButton(typeOfDocs)}
+ iconType={iconType}
+ >
+ Load
+
+
+
+
+
+ onChange(e)}
+ aria-label={typeOfDocs === 'new' ? 'fetch newer events' : 'fetch older events'}
+ min={0}
+ max={10000}
+ onKeyDown={(e) => handleKeyDown(e, typeOfDocs)}
+ />
+
+
+
+
+ {typeOfDocs === 'new' ? 'newer' : 'older'} events
+
+
+
+ );
+ };
+
+ const flyoutBody = (
+
+ {getInputForm('arrowUp', onChangeNewEvents, numNewEvents, 'new')}
+
+
+ {newEventsError !== '' && (
+
+ )}
+
+ {populateDataGrid(
+ explorerFields,
+ getHeaders(explorerFields.queriedFields, DEFAULT_COLUMNS.slice(1), true),
+ <>
+ {newEventsData}
+ {memorizedTds}
+ {oldEventsData}
+ >,
+ getHeaders(explorerFields.selectedFields, DEFAULT_COLUMNS.slice(1), true),
+ <>
+ {newEventsData}
+ {memorizedTds}
+ {oldEventsData}
+ >
+ )}
+
+ {oldEventsError !== '' && (
+
+ )}
+
+
+ {getInputForm('arrowDown', onChangeOldEvents, valueOldEvents, 'old')}
+
+ );
+
+ const flyoutFooter = <>>;
+
+ useEffect(() => {
+ loadData('new', 5);
+ loadData('old', 5);
+ }, []);
+
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/docTable/trace_block/trace_block.tsx b/dashboards-observability/public/components/explorer/docTable/trace_block/trace_block.tsx
new file mode 100644
index 000000000..6227666e8
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/docTable/trace_block/trace_block.tsx
@@ -0,0 +1,47 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { TraceDetailRender } from '../../../application_analytics/components/flyout_components/trace_detail_render';
+import React, { useEffect } from 'react';
+import { HttpSetup } from '../../../../../../../src/core/public';
+import { EuiCallOut, EuiLink } from '@elastic/eui';
+import { TRACE_ANALYTICS_DOCUMENTATION_LINK } from '../../../../../common/constants/trace_analytics';
+import {
+ OPEN_TELEMETRY_LOG_CORRELATION_LINK,
+ OTEL_TRACE_ID,
+} from '../../../../../common/constants/explorer';
+import { IDocType } from '../docViewRow';
+import { isValidTraceId } from '../../utils';
+
+interface props {
+ http: HttpSetup;
+ hit: IDocType;
+ logTraceId: string;
+}
+
+export const TraceBlock = ({ http, hit, logTraceId }: props) => {
+ if (logTraceId === '' || !isValidTraceId(logTraceId)) {
+ return (
+ <>
+
+ Please make sure to add "{OTEL_TRACE_ID}" field to the logs.
+
+ More info on{' '}
+
+ Trace Analytics
+
+
+ More info on{' '}
+
+ Log Correlation
+
+
+
+ >
+ );
+ }
+
+ return ;
+};
diff --git a/dashboards-observability/public/components/explorer/event_analytics.tsx b/dashboards-observability/public/components/explorer/event_analytics.tsx
new file mode 100644
index 000000000..7690e474d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/event_analytics.tsx
@@ -0,0 +1,121 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiGlobalToastList } from '@elastic/eui';
+import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
+import { EmptyTabParams } from 'common/types/explorer';
+import { isEmpty } from 'lodash';
+import React, { ReactChild, useState } from 'react';
+import { HashRouter, Route, Switch, useHistory } from 'react-router-dom';
+import { RAW_QUERY } from '../../../common/constants/explorer';
+import { ObservabilitySideBar } from '../common/side_nav';
+import { Home as EventExplorerHome } from './home';
+import { LogExplorer } from './log_explorer';
+
+export const EventAnalytics = ({
+ chrome,
+ parentBreadcrumbs,
+ pplService,
+ dslService,
+ savedObjects,
+ timestampUtils,
+ http,
+ notifications,
+ ...props
+}: any) => {
+ const history = useHistory();
+ const [toasts, setToasts] = useState([]);
+
+ const eventAnalyticsBreadcrumb = {
+ text: 'Event analytics',
+ href: '#/event_analytics',
+ };
+
+ const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => {
+ if (!text) text = '';
+ setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]);
+ };
+
+ const getExistingEmptyTab = ({ tabIds, queries, explorerData }: EmptyTabParams) => {
+ let emptyTabId = '';
+ for (let i = 0; i < tabIds!.length; i++) {
+ const tid = tabIds![i];
+ if (isEmpty(queries[tid][RAW_QUERY]) && isEmpty(explorerData[tid])) {
+ emptyTabId = tid;
+ break;
+ }
+ }
+ return emptyTabId;
+ };
+
+ return (
+ <>
+ {
+ setToasts(toasts.filter((toast) => toast.id !== removedToast.id));
+ }}
+ toastLifeTimeMs={6000}
+ />
+
+
+ {
+ chrome.setBreadcrumbs([
+ ...parentBreadcrumbs,
+ eventAnalyticsBreadcrumb,
+ {
+ text: 'Explorer',
+ href: `#/event_analytics/explorer`,
+ },
+ ]);
+ return (
+
+ );
+ }}
+ />
+ {
+ chrome.setBreadcrumbs([
+ ...parentBreadcrumbs,
+ eventAnalyticsBreadcrumb,
+ {
+ text: 'Home',
+ href: '#/event_analytics',
+ },
+ ]);
+ return (
+
+
+
+ );
+ }}
+ />
+
+
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/explorer.scss b/dashboards-observability/public/components/explorer/explorer.scss
new file mode 100644
index 000000000..423e226e3
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/explorer.scss
@@ -0,0 +1,17 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+ .liveStream {
+ margin : 8px;
+ height: 40px;
+ align-items: center;
+ justify-content: center;
+ flex-direction: row;
+ display: flex;
+ flex-grow: 1;
+ vertical-align: baseline;
+ }
+
+
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/explorer.tsx b/dashboards-observability/public/components/explorer/explorer.tsx
new file mode 100644
index 000000000..27cb168fa
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/explorer.tsx
@@ -0,0 +1,1176 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import './explorer.scss';
+import React, { useState, useMemo, useEffect, useRef, useCallback, ReactElement } from 'react';
+import { batch, useDispatch, useSelector } from 'react-redux';
+import { isEmpty, cloneDeep, isEqual, has, reduce } from 'lodash';
+import { FormattedMessage } from '@osd/i18n/react';
+import { EuiLoadingSpinner, EuiSpacer } from '@elastic/eui';
+import {
+ EuiText,
+ EuiButtonIcon,
+ EuiTabbedContent,
+ EuiTabbedContentTab,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLink,
+ EuiContextMenuItem,
+} from '@elastic/eui';
+import dateMath from '@elastic/datemath';
+import classNames from 'classnames';
+import { Search } from '../common/search/search';
+import { CountDistribution } from './visualizations/count_distribution';
+import { DataGrid } from './data_grid';
+import { Sidebar } from './sidebar';
+import { NoResults } from './no_results';
+import { HitsCounter } from './hits_counter/hits_counter';
+import { TimechartHeader } from './timechart_header';
+import { ExplorerVisualizations } from './visualizations';
+import { IField, IQueryTab, IDefaultTimestampState } from '../../../common/types/explorer';
+import {
+ TAB_CHART_TITLE,
+ TAB_EVENT_TITLE,
+ RAW_QUERY,
+ SELECTED_DATE_RANGE,
+ SELECTED_FIELDS,
+ SELECTED_TIMESTAMP,
+ AVAILABLE_FIELDS,
+ TIME_INTERVAL_OPTIONS,
+ SAVED_QUERY,
+ SAVED_VISUALIZATION,
+ SAVED_OBJECT_ID,
+ SAVED_OBJECT_TYPE,
+ NEW_TAB,
+ TAB_CREATED_TYPE,
+ EVENT_ANALYTICS_DOCUMENTATION_URL,
+ TAB_EVENT_ID,
+ TAB_CHART_ID,
+ DEFAULT_AVAILABILITY_QUERY,
+ DATE_PICKER_FORMAT,
+} from '../../../common/constants/explorer';
+import {
+ PPL_STATS_REGEX,
+ PPL_NEWLINE_REGEX,
+ LIVE_OPTIONS,
+ LIVE_END_TIME,
+} from '../../../common/constants/shared';
+import { getIndexPatternFromRawQuery, preprocessQuery, buildQuery } from '../../../common/utils';
+import { useFetchEvents, useFetchVisualizations } from './hooks';
+import { changeQuery, changeDateRange, selectQueries } from './slices/query_slice';
+import { selectQueryResult } from './slices/query_result_slice';
+import { selectFields, updateFields, sortFields } from './slices/field_slice';
+import { updateTabName } from './slices/query_tab_slice';
+import { selectCountDistribution } from './slices/count_distribution_slice';
+import { selectExplorerVisualization } from './slices/visualization_slice';
+import {
+ selectVisualizationConfig,
+ change as changeVisualizationConfig,
+} from './slices/viualization_config_slice';
+import { change as updateVizConfig } from './slices/viualization_config_slice';
+import { IExplorerProps, IVisualizationContainerProps } from '../../../common/types/explorer';
+import { TabContext } from './hooks';
+import { getVizContainerProps } from '../visualizations/charts/helpers';
+import { parseGetSuggestions, onItemSelect } from '../common/search/autocomplete_logic';
+import { formatError } from './utils';
+import { sleep } from '../common/live_tail/live_tail_button';
+
+const TYPE_TAB_MAPPING = {
+ [SAVED_QUERY]: TAB_EVENT_ID,
+ [SAVED_VISUALIZATION]: TAB_CHART_ID,
+};
+
+export const Explorer = ({
+ pplService,
+ dslService,
+ tabId,
+ savedObjects,
+ timestampUtils,
+ setToast,
+ http,
+ history,
+ notifications,
+ savedObjectId,
+ curSelectedTabId,
+ searchBarConfigs,
+ appId = '',
+ appBaseQuery = '',
+ addVisualizationToPanel,
+ startTime,
+ endTime,
+ setStartTime,
+ setEndTime,
+ callback,
+ callbackInApp,
+}: IExplorerProps) => {
+ const dispatch = useDispatch();
+ const requestParams = { tabId };
+ const { getLiveTail, getEvents, getAvailableFields, isEventsLoading } = useFetchEvents({
+ pplService,
+ requestParams,
+ });
+ const { getVisualizations, getCountVisualizations, isVisLoading } = useFetchVisualizations({
+ pplService,
+ requestParams,
+ });
+ const appLogEvents = tabId.startsWith('application-analytics-tab');
+ const query = useSelector(selectQueries)[tabId];
+ const explorerData = useSelector(selectQueryResult)[tabId];
+ const explorerFields = useSelector(selectFields)[tabId];
+ const countDistribution = useSelector(selectCountDistribution)[tabId];
+ const explorerVisualizations = useSelector(selectExplorerVisualization)[tabId];
+ const userVizConfigs = useSelector(selectVisualizationConfig)[tabId] || {};
+ const [selectedContentTabId, setSelectedContentTab] = useState(TAB_EVENT_ID);
+ const [selectedCustomPanelOptions, setSelectedCustomPanelOptions] = useState([]);
+ const [selectedPanelName, setSelectedPanelName] = useState('');
+ const [curVisId, setCurVisId] = useState('bar');
+ const [prevIndex, setPrevIndex] = useState('');
+ const [isPanelTextFieldInvalid, setIsPanelTextFieldInvalid] = useState(false);
+ const [isSidebarClosed, setIsSidebarClosed] = useState(false);
+ const [timeIntervalOptions, setTimeIntervalOptions] = useState(TIME_INTERVAL_OPTIONS);
+ const [isOverridingTimestamp, setIsOverridingTimestamp] = useState(false);
+ const [tempQuery, setTempQuery] = useState(query[RAW_QUERY]);
+ const [isLiveTailPopoverOpen, setIsLiveTailPopoverOpen] = useState(false);
+ const [isLiveTailOn, setIsLiveTailOn] = useState(false);
+ const [liveTailTabId, setLiveTailTabId] = useState(TAB_EVENT_ID);
+ const [liveTailName, setLiveTailName] = useState('Live');
+ const [liveHits, setLiveHits] = useState(0);
+ const [browserTabFocus, setBrowserTabFocus] = useState(true);
+ const [liveTimestamp, setLiveTimestamp] = useState(DATE_PICKER_FORMAT);
+ const [triggerAvailability, setTriggerAvailability] = useState(false);
+
+ const queryRef = useRef();
+ const appBasedRef = useRef('');
+ appBasedRef.current = appBaseQuery;
+ const selectedPanelNameRef = useRef('');
+ const explorerFieldsRef = useRef();
+ const isLiveTailOnRef = useRef(false);
+ const liveTailTabIdRef = useRef('');
+ const liveTailNameRef = useRef('Live');
+ queryRef.current = query;
+ selectedPanelNameRef.current = selectedPanelName;
+ explorerFieldsRef.current = explorerFields;
+ isLiveTailOnRef.current = isLiveTailOn;
+ liveTailTabIdRef.current = liveTailTabId;
+ liveTailNameRef.current = liveTailName;
+
+ let minInterval = 'y';
+ const findAutoInterval = (start: string = '', end: string = '') => {
+ if (start?.length === 0 || end?.length === 0 || start === end)
+ return ['d', [...TIME_INTERVAL_OPTIONS]];
+ const momentStart = dateMath.parse(start)!;
+ const momentEnd = dateMath.parse(end)!;
+ const diffSeconds = momentEnd.unix() - momentStart.unix();
+
+ // less than 1 second
+ if (diffSeconds <= 1) minInterval = 'ms';
+ // less than 2 minutes
+ else if (diffSeconds <= 60 * 2) minInterval = 's';
+ // less than 2 hours
+ else if (diffSeconds <= 3600 * 2) minInterval = 'm';
+ // less than 2 days
+ else if (diffSeconds <= 86400 * 2) minInterval = 'h';
+ // less than 1 month
+ else if (diffSeconds <= 86400 * 31) minInterval = 'd';
+ // less than 3 months
+ else if (diffSeconds <= 86400 * 93) minInterval = 'w';
+ // less than 1 year
+ else if (diffSeconds <= 86400 * 366) minInterval = 'M';
+
+ setTimeIntervalOptions([
+ { text: 'Auto', value: 'auto_' + minInterval },
+ ...TIME_INTERVAL_OPTIONS,
+ ]);
+ };
+
+ useEffect(() => {
+ document.addEventListener('visibilitychange', function () {
+ if (document.hidden) {
+ setBrowserTabFocus(false);
+ } else {
+ setBrowserTabFocus(true);
+ }
+ });
+ });
+
+ const composeFinalQuery = (
+ curQuery: any,
+ startingTime: string,
+ endingTime: string,
+ timeField: string,
+ isLiveQuery: boolean
+ ) => {
+ const fullQuery = buildQuery(appBasedRef.current, curQuery![RAW_QUERY]);
+ if (isEmpty(fullQuery)) return '';
+ return preprocessQuery({
+ rawQuery: fullQuery,
+ startTime: startingTime,
+ endTime: endingTime,
+ timeField,
+ isLiveQuery,
+ });
+ };
+
+ const getSavedDataById = async (objectId: string) => {
+ // load saved query/visualization if object id exists
+ await savedObjects
+ .fetchSavedObjects({
+ objectId,
+ })
+ .then(async (res) => {
+ const savedData = res.observabilityObjectList[0];
+ const isSavedQuery = has(savedData, SAVED_QUERY);
+ const savedType = isSavedQuery ? SAVED_QUERY : SAVED_VISUALIZATION;
+ const objectData = isSavedQuery ? savedData.savedQuery : savedData.savedVisualization;
+ const currQuery = appLogEvents
+ ? objectData?.query.replace(appBaseQuery + '| ', '')
+ : objectData?.query || '';
+
+ if (appLogEvents) {
+ if (objectData?.selected_date_range?.start && objectData?.selected_date_range?.end) {
+ setStartTime(objectData.selected_date_range.start);
+ setEndTime(objectData.selected_date_range.end);
+ }
+ }
+
+ // update redux
+ batch(async () => {
+ await dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [RAW_QUERY]: currQuery,
+ [SELECTED_TIMESTAMP]: objectData?.selected_timestamp?.name || 'timestamp',
+ [SAVED_OBJECT_ID]: objectId,
+ [SAVED_OBJECT_TYPE]: savedType,
+ [SELECTED_DATE_RANGE]:
+ objectData?.selected_date_range?.start && objectData?.selected_date_range?.end
+ ? [objectData.selected_date_range.start, objectData.selected_date_range.end]
+ : ['now-15m', 'now'],
+ },
+ })
+ );
+ await dispatch(
+ updateFields({
+ tabId,
+ data: {
+ [SELECTED_FIELDS]: [...objectData?.selected_fields?.tokens],
+ },
+ })
+ );
+ await dispatch(
+ updateTabName({
+ tabId,
+ tabName: objectData.name,
+ })
+ );
+ // fill saved user configs
+ if (objectData?.type) {
+ await dispatch(
+ updateVizConfig({
+ tabId,
+ vizId: objectData?.type,
+ data: JSON.parse(objectData.user_configs),
+ })
+ );
+ }
+ });
+
+ // update UI state with saved data
+ setSelectedPanelName(objectData?.name || '');
+ setCurVisId(objectData?.type || 'bar');
+ setTempQuery((staleTempQuery: string) => {
+ return appLogEvents ? currQuery : objectData?.query || staleTempQuery;
+ });
+ const tabToBeFocused = isSavedQuery
+ ? TYPE_TAB_MAPPING[SAVED_QUERY]
+ : TYPE_TAB_MAPPING[SAVED_VISUALIZATION];
+ setSelectedContentTab(tabToBeFocused);
+ await fetchData();
+ })
+ .catch((error) => {
+ notifications.toasts.addError(error, {
+ title: `Cannot get saved data for object id: ${objectId}`,
+ });
+ });
+ };
+
+ const getDefaultTimestampByIndexPattern = async (
+ indexPattern: string
+ ): Promise => await timestampUtils.getTimestamp(indexPattern);
+
+ const fetchData = async (startingTime?: string, endingTime?: string) => {
+ const curQuery = queryRef.current;
+ const rawQueryStr = buildQuery(appBasedRef.current, curQuery![RAW_QUERY]);
+ const curIndex = getIndexPatternFromRawQuery(rawQueryStr);
+ if (isEmpty(rawQueryStr)) return;
+
+ if (isEmpty(curIndex)) {
+ setToast('Query does not include valid index.', 'danger');
+ return;
+ }
+
+ let curTimestamp: string = curQuery![SELECTED_TIMESTAMP];
+
+ if (isEmpty(curTimestamp)) {
+ const defaultTimestamp = await getDefaultTimestampByIndexPattern(curIndex);
+ if (isEmpty(defaultTimestamp.default_timestamp)) {
+ setToast(defaultTimestamp.message, 'danger');
+ return;
+ }
+ curTimestamp = defaultTimestamp.default_timestamp;
+ if (defaultTimestamp.hasSchemaConflict) {
+ setToast(defaultTimestamp.message, 'danger');
+ }
+ }
+
+ if (isEqual(typeof startingTime, 'undefined') && isEqual(typeof endingTime, 'undefined')) {
+ startingTime = curQuery![SELECTED_DATE_RANGE][0];
+ endingTime = curQuery![SELECTED_DATE_RANGE][1];
+ }
+
+ // compose final query
+ const finalQuery = composeFinalQuery(
+ curQuery,
+ startingTime!,
+ endingTime!,
+ curTimestamp,
+ isLiveTailOnRef.current
+ );
+
+ await dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ finalQuery,
+ [SELECTED_TIMESTAMP]: curTimestamp,
+ },
+ })
+ );
+
+ // search
+ if (finalQuery.match(PPL_STATS_REGEX)) {
+ getVisualizations();
+ getAvailableFields(`search source=${curIndex}`);
+ } else {
+ findAutoInterval(startTime, endTime);
+ if (isLiveTailOnRef.current) {
+ getLiveTail(undefined, (error) => {
+ const formattedError = formatError(error.name, error.message, error.body.message);
+ notifications.toasts.addError(formattedError, {
+ title: 'Error fetching events',
+ });
+ });
+ } else {
+ getEvents(undefined, (error) => {
+ const formattedError = formatError(error.name, error.message, error.body.message);
+ notifications.toasts.addError(formattedError, {
+ title: 'Error fetching events',
+ });
+ });
+ }
+ getCountVisualizations(minInterval);
+ }
+
+ // for comparing usage if for the same tab, user changed index from one to another
+ if (!isLiveTailOnRef.current) {
+ setPrevIndex(curTimestamp);
+ if (!queryRef.current!.isLoaded) {
+ dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ isLoaded: true,
+ },
+ })
+ );
+ }
+ }
+ };
+
+ const isIndexPatternChanged = (currentQuery: string, prevTabQuery: string) =>
+ !isEqual(getIndexPatternFromRawQuery(currentQuery), getIndexPatternFromRawQuery(prevTabQuery));
+
+ const updateTabData = async (objectId: string) => {
+ await getSavedDataById(objectId);
+ };
+
+ const prepareAvailability = async () => {
+ setSelectedContentTab(TAB_CHART_ID);
+ setTriggerAvailability(true);
+ await setTempQuery(DEFAULT_AVAILABILITY_QUERY);
+ await updateQueryInStore(DEFAULT_AVAILABILITY_QUERY);
+ await handleTimeRangePickerRefresh(true);
+ };
+
+ useEffect(() => {
+ if (!isEmpty(appBasedRef.current)) {
+ if (callback) {
+ callback(() => prepareAvailability());
+ }
+ if (callbackInApp) {
+ callbackInApp(() => prepareAvailability());
+ }
+ }
+ }, [appBasedRef.current]);
+
+ useEffect(() => {
+ if (queryRef.current!.isLoaded) return;
+ let objectId;
+ if (queryRef.current![TAB_CREATED_TYPE] === NEW_TAB || appLogEvents) {
+ objectId = queryRef.current!.savedObjectId || '';
+ } else {
+ objectId = queryRef.current!.savedObjectId || savedObjectId;
+ }
+ if (objectId) {
+ updateTabData(objectId);
+ } else {
+ fetchData();
+ }
+ }, []);
+
+ useEffect(() => {
+ if (appLogEvents) {
+ if (savedObjectId) {
+ updateTabData(savedObjectId);
+ }
+ }
+ }, [savedObjectId]);
+
+ const handleAddField = (field: IField) => toggleFields(field, AVAILABLE_FIELDS, SELECTED_FIELDS);
+
+ const handleRemoveField = (field: IField) =>
+ toggleFields(field, SELECTED_FIELDS, AVAILABLE_FIELDS);
+
+ const handleTimePickerChange = async (timeRange: string[]) => {
+ if (appLogEvents) {
+ setStartTime(timeRange[0]);
+ setEndTime(timeRange[1]);
+ }
+ await dispatch(
+ changeDateRange({
+ tabId: requestParams.tabId,
+ data: {
+ [RAW_QUERY]: queryRef.current![RAW_QUERY],
+ [SELECTED_DATE_RANGE]: timeRange,
+ },
+ })
+ );
+ };
+
+ const showPermissionErrorToast = () => {
+ setToast(
+ 'Please ask your administrator to enable Event Analytics for you.',
+ 'danger',
+
+ Documentation
+
+ );
+ };
+
+ const handleTimeRangePickerRefresh = (availability?: boolean) => {
+ handleQuerySearch(availability);
+ };
+
+ /**
+ * Toggle fields between selected and unselected sets
+ * @param field field to be toggled
+ * @param FieldSetToRemove set where this field to be removed from
+ * @param FieldSetToAdd set where this field to be added
+ */
+ const toggleFields = (field: IField, FieldSetToRemove: string, FieldSetToAdd: string) => {
+ const nextFields = cloneDeep(explorerFields);
+ const thisFieldSet = nextFields[FieldSetToRemove];
+ const nextFieldSet = thisFieldSet.filter((fd: IField) => fd.name !== field.name);
+ nextFields[FieldSetToRemove] = nextFieldSet;
+ nextFields[FieldSetToAdd].push(field);
+ batch(() => {
+ dispatch(
+ updateFields({
+ tabId,
+ data: {
+ ...nextFields,
+ },
+ })
+ );
+ dispatch(
+ sortFields({
+ tabId,
+ data: [FieldSetToAdd],
+ })
+ );
+ });
+ };
+
+ const sidebarClassName = classNames({
+ closed: isSidebarClosed,
+ });
+
+ const mainSectionClassName = classNames({
+ 'col-md-10': !isSidebarClosed,
+ 'col-md-12': isSidebarClosed,
+ });
+
+ const handleOverrideTimestamp = async (timestamp: IField) => {
+ const curQuery = queryRef.current;
+ const rawQueryStr = buildQuery(appBaseQuery, curQuery![RAW_QUERY]);
+ const curIndex = getIndexPatternFromRawQuery(rawQueryStr);
+ if (isEmpty(rawQueryStr) || isEmpty(curIndex)) {
+ setToast('Cannot override timestamp because there was no valid index found.', 'danger');
+ return;
+ }
+
+ setIsOverridingTimestamp(true);
+
+ await dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [SELECTED_TIMESTAMP]: timestamp?.name || '',
+ },
+ })
+ );
+
+ setIsOverridingTimestamp(false);
+ handleQuerySearch();
+ };
+
+ const totalHits: number = useMemo(() => {
+ if (isLiveTailOn && countDistribution?.data) {
+ const hits = reduce(
+ countDistribution.data['count()'],
+ (sum, n) => {
+ return sum + n;
+ },
+ liveHits
+ );
+ setLiveHits(hits);
+ return hits;
+ }
+ return 0;
+ }, [countDistribution?.data]);
+
+ const getMainContent = () => {
+ return (
+
+
+
+
+ {explorerData && !isEmpty(explorerData.jsonData) ? (
+
+
+ {countDistribution?.data && !isLiveTailOnRef.current && (
+ <>
+
+
+ {
+ return sum + n;
+ },
+ 0
+ )}
+ showResetButton={false}
+ onResetQuery={() => {}}
+ />
+
+
+ {
+ getCountVisualizations(intrv);
+ }}
+ stateInterval="auto"
+ />
+
+
+
+ >
+ )}
+
+
+
+
+
+
+ {isLiveTailOnRef.current && (
+ <>
+
+
+
+
+ Live streaming
+
+
+ {}}
+ />
+
+ since {liveTimestamp}
+
+
+ >
+ )}
+
+
+
+
+
+
+
+
+ ) : (
+
+ )}
+
+
+
+ );
+ };
+
+ function getMainContentTab({
+ tabID,
+ tabTitle,
+ getContent,
+ }: {
+ tabID: string;
+ tabTitle: string;
+ getContent: () => JSX.Element;
+ }) {
+ return {
+ id: tabID,
+ name: (
+ <>
+
+ {tabTitle}
+
+ >
+ ),
+ content: <>{getContent()}>,
+ };
+ }
+
+ const visualizations: IVisualizationContainerProps = useMemo(() => {
+ return getVizContainerProps({
+ vizId: curVisId,
+ rawVizData: explorerVisualizations,
+ query,
+ indexFields: explorerFields,
+ userConfigs: userVizConfigs[curVisId] || {},
+ appData: { fromApp: appLogEvents },
+ });
+ }, [curVisId, explorerVisualizations, explorerFields, query, userVizConfigs]);
+
+ const callbackForConfig = (childFunc: () => void) => {
+ if (childFunc && triggerAvailability) {
+ childFunc();
+ setTriggerAvailability(false);
+ }
+ };
+
+ const getExplorerVis = () => {
+ return (
+
+ );
+ };
+
+ const getMainContentTabs = () => {
+ return [
+ getMainContentTab({
+ tabID: TAB_EVENT_ID,
+ tabTitle: TAB_EVENT_TITLE,
+ getContent: () => getMainContent(),
+ }),
+ getMainContentTab({
+ tabID: TAB_CHART_ID,
+ tabTitle: TAB_CHART_TITLE,
+ getContent: () => getExplorerVis(),
+ }),
+ ];
+ };
+
+ const memorizedMainContentTabs = useMemo(() => {
+ return getMainContentTabs();
+ }, [
+ curVisId,
+ isPanelTextFieldInvalid,
+ explorerData,
+ explorerFields,
+ isSidebarClosed,
+ countDistribution,
+ explorerVisualizations,
+ selectedContentTabId,
+ isOverridingTimestamp,
+ visualizations,
+ query,
+ isLiveTailOnRef.current,
+ ]);
+
+ const handleContentTabClick = (selectedTab: IQueryTab) => setSelectedContentTab(selectedTab.id);
+
+ const updateQueryInStore = async (updateQuery: string) => {
+ await dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [RAW_QUERY]: updateQuery.replaceAll(PPL_NEWLINE_REGEX, ''),
+ },
+ })
+ );
+ };
+
+ const updateCurrentTimeStamp = async (timestamp: string) => {
+ await dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [SELECTED_TIMESTAMP]: timestamp,
+ },
+ })
+ );
+ };
+
+ const handleQuerySearch = useCallback(
+ async (availability?: boolean) => {
+ // clear previous selected timestamp when index pattern changes
+ if (
+ !isEmpty(tempQuery) &&
+ !isEmpty(query[RAW_QUERY]) &&
+ isIndexPatternChanged(tempQuery, query[RAW_QUERY])
+ ) {
+ await updateCurrentTimeStamp('');
+ }
+ if (availability !== true) {
+ await updateQueryInStore(tempQuery);
+ }
+ fetchData();
+ },
+ [tempQuery, query[RAW_QUERY]]
+ );
+
+ const handleQueryChange = async (newQuery: string) => {
+ setTempQuery(newQuery);
+ };
+
+ const handleSavingObject = async () => {
+ const currQuery = queryRef.current;
+ const currFields = explorerFieldsRef.current;
+ if (isEmpty(currQuery![RAW_QUERY]) && isEmpty(appBaseQuery)) {
+ setToast('No query to save.', 'danger');
+ return;
+ }
+ if (isEmpty(selectedPanelNameRef.current)) {
+ setIsPanelTextFieldInvalid(true);
+ setToast('Name field cannot be empty.', 'danger');
+ return;
+ }
+ setIsPanelTextFieldInvalid(false);
+ if (isEqual(selectedContentTabId, TAB_EVENT_ID)) {
+ const isTabMatchingSavedType = isEqual(currQuery![SAVED_OBJECT_TYPE], SAVED_QUERY);
+ if (!isEmpty(currQuery![SAVED_OBJECT_ID]) && isTabMatchingSavedType) {
+ await savedObjects
+ .updateSavedQueryById({
+ query: currQuery![RAW_QUERY],
+ fields: currFields![SELECTED_FIELDS],
+ dateRange: currQuery![SELECTED_DATE_RANGE],
+ name: selectedPanelNameRef.current,
+ timestamp: currQuery![SELECTED_TIMESTAMP],
+ objectId: currQuery![SAVED_OBJECT_ID],
+ type: '',
+ })
+ .then((res: any) => {
+ setToast(
+ `Query '${selectedPanelNameRef.current}' has been successfully updated.`,
+ 'success'
+ );
+ dispatch(
+ updateTabName({
+ tabId,
+ tabName: selectedPanelNameRef.current,
+ })
+ );
+ return res;
+ })
+ .catch((error: any) => {
+ notifications.toasts.addError(error, {
+ title: `Cannot update query '${selectedPanelNameRef.current}'`,
+ });
+ });
+ } else {
+ // create new saved query
+ savedObjects
+ .createSavedQuery({
+ query: currQuery![RAW_QUERY],
+ fields: currFields![SELECTED_FIELDS],
+ dateRange: currQuery![SELECTED_DATE_RANGE],
+ name: selectedPanelNameRef.current,
+ timestamp: currQuery![SELECTED_TIMESTAMP],
+ objectId: '',
+ type: '',
+ })
+ .then((res: any) => {
+ history.replace(`/event_analytics/explorer/${res.objectId}`);
+ setToast(
+ `New query '${selectedPanelNameRef.current}' has been successfully saved.`,
+ 'success'
+ );
+ batch(() => {
+ dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [SAVED_OBJECT_ID]: res.objectId,
+ [SAVED_OBJECT_TYPE]: SAVED_QUERY,
+ },
+ })
+ );
+ dispatch(
+ updateTabName({
+ tabId,
+ tabName: selectedPanelNameRef.current,
+ })
+ );
+ });
+ history.replace(`/event_analytics/explorer/${res.objectId}`);
+ return res;
+ })
+ .catch((error: any) => {
+ if (error?.body?.statusCode === 403) {
+ showPermissionErrorToast();
+ } else {
+ notifications.toasts.addError(error, {
+ title: `Cannot save query '${selectedPanelNameRef.current}'`,
+ });
+ }
+ });
+ }
+ // to-dos - update selected custom panel
+ if (!isEmpty(selectedCustomPanelOptions)) {
+ // update custom panel - query
+ }
+ } else if (isEqual(selectedContentTabId, TAB_CHART_ID)) {
+ if (
+ (isEmpty(currQuery![RAW_QUERY]) && isEmpty(appBaseQuery)) ||
+ isEmpty(explorerVisualizations)
+ ) {
+ setToast(`There is no query or(and) visualization to save`, 'danger');
+ return;
+ }
+ let savingVisRes;
+ const vizDescription = userVizConfigs[curVisId]?.dataConfig?.panelOptions?.description || '';
+ const isTabMatchingSavedType = isEqual(currQuery![SAVED_OBJECT_TYPE], SAVED_VISUALIZATION);
+ if (!isEmpty(currQuery![SAVED_OBJECT_ID]) && isTabMatchingSavedType) {
+ savingVisRes = await savedObjects
+ .updateSavedVisualizationById({
+ query: buildQuery(appBaseQuery, currQuery![RAW_QUERY]),
+ fields: currFields![SELECTED_FIELDS],
+ dateRange: currQuery![SELECTED_DATE_RANGE],
+ name: selectedPanelNameRef.current,
+ timestamp: currQuery![SELECTED_TIMESTAMP],
+ objectId: currQuery![SAVED_OBJECT_ID],
+ type: curVisId,
+ userConfigs: userVizConfigs.hasOwnProperty(curVisId)
+ ? JSON.stringify(userVizConfigs[curVisId])
+ : JSON.stringify({}),
+ description: vizDescription,
+ })
+ .then((res: any) => {
+ setToast(
+ `Visualization '${selectedPanelNameRef.current}' has been successfully updated.`,
+ 'success'
+ );
+ dispatch(
+ updateTabName({
+ tabId,
+ tabName: selectedPanelNameRef.current,
+ })
+ );
+ return res;
+ })
+ .catch((error: any) => {
+ notifications.toasts.addError(error, {
+ title: `Cannot update Visualization '${selectedPanelNameRef.current}'`,
+ });
+ });
+ } else {
+ // create new saved visualization
+ savingVisRes = await savedObjects
+ .createSavedVisualization({
+ query: buildQuery(appBaseQuery, currQuery![RAW_QUERY]),
+ fields: currFields![SELECTED_FIELDS],
+ dateRange: currQuery![SELECTED_DATE_RANGE],
+ type: curVisId,
+ name: selectedPanelNameRef.current,
+ timestamp: currQuery![SELECTED_TIMESTAMP],
+ applicationId: appId,
+ userConfigs: userVizConfigs.hasOwnProperty(curVisId)
+ ? JSON.stringify(userVizConfigs[curVisId])
+ : JSON.stringify({}),
+ description: vizDescription,
+ })
+ .then((res: any) => {
+ batch(() => {
+ dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [SAVED_OBJECT_ID]: res.objectId,
+ [SAVED_OBJECT_TYPE]: SAVED_VISUALIZATION,
+ },
+ })
+ );
+ dispatch(
+ updateTabName({
+ tabId,
+ tabName: selectedPanelNameRef.current,
+ })
+ );
+ });
+ if (appLogEvents) {
+ addVisualizationToPanel(res.objectId, selectedPanelNameRef.current);
+ } else {
+ history.replace(`/event_analytics/explorer/${res.objectId}`);
+ }
+ setToast(
+ `New visualization '${selectedPanelNameRef.current}' has been successfully saved.`,
+ 'success'
+ );
+ return res;
+ })
+ .catch((error: any) => {
+ notifications.toasts.addError(error, {
+ title: `Cannot save Visualization '${selectedPanelNameRef.current}'`,
+ });
+ });
+ }
+ if (!has(savingVisRes, 'objectId')) return;
+ // update custom panel - visualization
+ if (!isEmpty(selectedCustomPanelOptions)) {
+ savedObjects
+ .bulkUpdateCustomPanel({
+ selectedCustomPanels: selectedCustomPanelOptions,
+ savedVisualizationId: savingVisRes.objectId,
+ })
+ .then((res: any) => {
+ setToast(
+ `Visualization '${selectedPanelNameRef.current}' has been successfully saved to operation panels.`,
+ 'success'
+ );
+ })
+ .catch((error: any) => {
+ notifications.toasts.addError(error, {
+ title: `Cannot add Visualization '${selectedPanelNameRef.current}' to operation panels`,
+ });
+ });
+ }
+ }
+ };
+
+ const liveTailLoop = async (
+ name: string,
+ startingTime: string,
+ endingTime: string,
+ delayTime: number
+ ) => {
+ setLiveTailName(name);
+ setLiveTailTabId((curSelectedTabId.current as unknown) as string);
+ setIsLiveTailOn(true);
+ setToast('Live tail On', 'success');
+ setIsLiveTailPopoverOpen(false);
+ setLiveTimestamp(dateMath.parse(endingTime)?.utc().format(DATE_PICKER_FORMAT) || '');
+ setLiveHits(0);
+ await sleep(2000);
+ const curLiveTailname = liveTailNameRef.current;
+ while (isLiveTailOnRef.current === true && curLiveTailname === liveTailNameRef.current) {
+ handleLiveTailSearch(startingTime, endingTime);
+ if (liveTailTabIdRef.current !== curSelectedTabId.current) {
+ setIsLiveTailOn(false);
+ isLiveTailOnRef.current = false;
+ setLiveTailName('Live');
+ setLiveHits(0);
+ }
+ await sleep(delayTime);
+ }
+ };
+
+ const stopLive = () => {
+ setLiveTailName('Live');
+ setIsLiveTailOn(false);
+ setLiveHits(0);
+ setIsLiveTailPopoverOpen(false);
+ if (isLiveTailOnRef.current) setToast('Live tail Off', 'danger');
+ };
+
+ useEffect(() => {
+ if (isEqual(selectedContentTabId, TAB_CHART_ID) || !browserTabFocus) {
+ stopLive();
+ }
+ }, [selectedContentTabId, browserTabFocus]);
+
+ // stop live tail if the page is moved using breadcrumbs
+ let lastUrl = location.href;
+ new MutationObserver(() => {
+ const url = location.href;
+ if (url !== lastUrl) {
+ lastUrl = url;
+ stopLive();
+ }
+ }).observe(document, { subtree: true, childList: true });
+
+ const popoverItems: ReactElement[] = LIVE_OPTIONS.map((e) => {
+ return (
+ {
+ liveTailLoop(e.label, e.startTime, LIVE_END_TIME, e.delayTime);
+ }}
+ data-test-subj={'eventLiveTail__delay' + e.label}
+ >
+ {e.label}
+
+ );
+ });
+
+ const dateRange =
+ isEmpty(startTime) || isEmpty(endTime)
+ ? isEmpty(query.selectedDateRange)
+ ? ['now-15m', 'now']
+ : [query.selectedDateRange[0], query.selectedDateRange[1]]
+ : [startTime, endTime];
+
+ const handleLiveTailSearch = useCallback(
+ async (startingTime: string, endingTime: string) => {
+ await updateQueryInStore(tempQuery);
+ fetchData(startingTime, endingTime);
+ },
+ [tempQuery]
+ );
+
+ return (
+
+
+ handleTimePickerChange(timeRange)}
+ selectedPanelName={selectedPanelNameRef.current}
+ selectedCustomPanelOptions={selectedCustomPanelOptions}
+ setSelectedPanelName={setSelectedPanelName}
+ setSelectedCustomPanelOptions={setSelectedCustomPanelOptions}
+ handleSavingObject={handleSavingObject}
+ isPanelTextFieldInvalid={isPanelTextFieldInvalid}
+ savedObjects={savedObjects}
+ showSavePanelOptionsList={isEqual(selectedContentTabId, TAB_CHART_ID)}
+ handleTimeRangePickerRefresh={handleTimeRangePickerRefresh}
+ isLiveTailPopoverOpen={isLiveTailPopoverOpen}
+ closeLiveTailPopover={() => setIsLiveTailPopoverOpen(false)}
+ popoverItems={popoverItems}
+ isLiveTailOn={isLiveTailOnRef.current}
+ selectedSubTabId={selectedContentTabId}
+ searchBarConfigs={searchBarConfigs}
+ getSuggestions={parseGetSuggestions}
+ onItemSelect={onItemSelect}
+ tabId={tabId}
+ baseQuery={appBaseQuery}
+ stopLive={stopLive}
+ setIsLiveTailPopoverOpen={setIsLiveTailPopoverOpen}
+ liveTailName={liveTailNameRef.current}
+ />
+ tab.id === selectedContentTabId)}
+ onTabClick={(selectedTab: EuiTabbedContentTab) => handleContentTabClick(selectedTab)}
+ tabs={memorizedMainContentTabs}
+ />
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/hits_counter/__tests__/__snapshots__/hits_counter.test.tsx.snap b/dashboards-observability/public/components/explorer/hits_counter/__tests__/__snapshots__/hits_counter.test.tsx.snap
new file mode 100644
index 000000000..13a8ec20c
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hits_counter/__tests__/__snapshots__/hits_counter.test.tsx.snap
@@ -0,0 +1,142 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Hits counter component Renders hits counter 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ 815
+
+
+
+ hits
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/hits_counter/__tests__/hits_counter.test.tsx b/dashboards-observability/public/components/explorer/hits_counter/__tests__/hits_counter.test.tsx
new file mode 100644
index 000000000..fca4b5fee
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hits_counter/__tests__/hits_counter.test.tsx
@@ -0,0 +1,32 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { HitsCounter } from '../hits_counter';
+
+describe('Hits counter component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders hits counter', async () => {
+ const onResetQuery = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/hits_counter/hits_counter.tsx b/dashboards-observability/public/components/explorer/hits_counter/hits_counter.tsx
new file mode 100644
index 000000000..8b7d3f1d0
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hits_counter/hits_counter.tsx
@@ -0,0 +1,71 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+import React from 'react';
+import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
+import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
+import { i18n } from '@osd/i18n';
+import { formatNumWithCommas } from '../../common/helpers';
+
+export interface HitsCounterProps {
+ /**
+ * the number of query hits
+ */
+ hits: number;
+ /**
+ * displays the reset button
+ */
+ showResetButton: boolean;
+ /**
+ * resets the query
+ */
+ onResetQuery: () => void;
+}
+
+export function HitsCounter({ hits, showResetButton, onResetQuery }: HitsCounterProps) {
+ return (
+
+
+
+
+ {formatNumWithCommas(hits)} {' '}
+
+
+
+ {showResetButton && (
+
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/hits_counter/index.ts b/dashboards-observability/public/components/explorer/hits_counter/index.ts
new file mode 100644
index 000000000..93706c494
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hits_counter/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { HitsCounter } from './hits_counter';
diff --git a/dashboards-observability/public/components/explorer/home.scss b/dashboards-observability/public/components/explorer/home.scss
new file mode 100644
index 000000000..bc4d8f66d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/home.scss
@@ -0,0 +1,20 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.event-home {
+ float: left;
+ width: 100%;
+ max-width: 1130px;
+ #autocomplete-textarea {
+ min-height: 80px;
+ }
+ .ppl-link {
+ right: 5px;
+ }
+}
+
+#home-his-title {
+ padding-left: 10px;
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/home.tsx b/dashboards-observability/public/components/explorer/home.tsx
new file mode 100644
index 000000000..3e10ad682
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/home.tsx
@@ -0,0 +1,472 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './home.scss';
+
+import React, { useState, ReactElement, useRef, useEffect } from 'react';
+import { useDispatch, batch, useSelector } from 'react-redux';
+import { uniqueId } from 'lodash';
+import { useHistory } from 'react-router-dom';
+import {
+ EuiPage,
+ EuiPageBody,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiTitle,
+ EuiPageContent,
+ EuiSpacer,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiButton,
+ EuiPopover,
+ EuiContextMenuPanel,
+ EuiContextMenuItem,
+ EuiOverlayMask,
+ EuiLink,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiText,
+ EuiHorizontalRule,
+} from '@elastic/eui';
+import { Search } from '../common/search/search';
+import { DeleteModal } from '../common/helpers/delete_modal';
+import {
+ RAW_QUERY,
+ TAB_ID_TXT_PFX,
+ SELECTED_DATE_RANGE,
+ EVENT_ANALYTICS_DOCUMENTATION_URL,
+ TAB_CREATED_TYPE,
+ NEW_TAB,
+ REDIRECT_TAB,
+} from '../../../common/constants/explorer';
+import {
+ OBSERVABILITY_BASE,
+ EVENT_ANALYTICS,
+ SAVED_OBJECTS,
+} from '../../../common/constants/shared';
+import { EmptyTabParams, SavedQueryRes, SavedVizRes } from '../../../common/types/explorer';
+import { HttpStart } from '../../../../../src/core/public';
+import SavedObjects from '../../services/saved_objects/event_analytics/saved_objects';
+import { addTab, selectQueryTabs } from './slices/query_tab_slice';
+import { init as initFields } from './slices/field_slice';
+import { init as initQuery, changeQuery } from './slices/query_slice';
+import { init as initQueryResult, selectQueryResult } from './slices/query_result_slice';
+import { SavedQueryTable } from './home_table/saved_query_table';
+import { selectQueries } from './slices/query_slice';
+import { setSelectedQueryTab } from './slices/query_tab_slice';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../common/constants/custom_panels';
+import { getSampleDataModal } from '../common/helpers/add_sample_modal';
+import { parseGetSuggestions, onItemSelect } from '../common/search/autocomplete_logic';
+
+interface IHomeProps {
+ pplService: any;
+ dslService: any;
+ savedObjects: SavedObjects;
+ setToast: (
+ title: string,
+ color?: string,
+ text?: React.ReactChild | undefined,
+ side?: string | undefined
+ ) => void;
+ getExistingEmptyTab: (params: EmptyTabParams) => string;
+ http: HttpStart;
+}
+
+export const Home = (props: IHomeProps) => {
+ const { pplService, dslService, savedObjects, setToast, getExistingEmptyTab, http } = props;
+ const history = useHistory();
+ const dispatch = useDispatch();
+
+ const queries = useSelector(selectQueries);
+ const explorerData = useSelector(selectQueryResult);
+ const tabIds = useSelector(selectQueryTabs).queryTabIds;
+ const queryRef = useRef();
+ const tabIdsRef = useRef();
+ const explorerDataRef = useRef();
+ queryRef.current = queries;
+ tabIdsRef.current = tabIds;
+ explorerDataRef.current = explorerData;
+
+ const [searchQuery, setSearchQuery] = useState('');
+ const [selectedDateRange, setSelectedDateRange] = useState(['now-15m', 'now']);
+ const [savedHistories, setSavedHistories] = useState([]);
+ const [selectedHistories, setSelectedHistories] = useState([]);
+ const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false);
+ const [isTableLoading, setIsTableLoading] = useState(false);
+ const [modalLayout, setModalLayout] = useState( );
+ const [isModalVisible, setIsModalVisible] = useState(false);
+ const selectedDateRangeRef = useRef();
+ selectedDateRangeRef.current = selectedDateRange;
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const fetchHistories = async () => {
+ const res = await savedObjects.fetchSavedObjects({
+ objectType: ['savedQuery', 'savedVisualization'],
+ sortOrder: 'desc',
+ fromIndex: 0,
+ });
+ const nonAppObjects = res.observabilityObjectList.filter(
+ (object: SavedQueryRes | SavedVizRes) =>
+ (object.savedVisualization && !object.savedVisualization.application_id) ||
+ object.savedQuery
+ );
+ setSavedHistories(nonAppObjects);
+ };
+
+ const deleteHistoryList = async () => {
+ const objectIdsToDelete = selectedHistories.map((history) => history.data.objectId);
+ await savedObjects
+ .deleteSavedObjectsList({ objectIdList: objectIdsToDelete })
+ .then(async (res) => {
+ setSavedHistories((staleHistories) => {
+ return staleHistories.filter((his) => {
+ return !objectIdsToDelete.includes(his.objectId);
+ });
+ });
+ setToast(`Histories has been successfully deleted.`, 'success');
+ })
+ .catch((error) => {
+ setToast(`Cannot delete Histories, error: ${error.message}`, 'danger');
+ })
+ .finally(() => {
+ closeModal();
+ });
+ };
+
+ const addNewTab = async () => {
+ // get a new tabId
+ const tabId = uniqueId(TAB_ID_TXT_PFX);
+
+ // create a new tab
+ await batch(() => {
+ dispatch(initQuery({ tabId }));
+ dispatch(initQueryResult({ tabId }));
+ dispatch(initFields({ tabId }));
+ dispatch(addTab({ tabId }));
+ });
+
+ return tabId;
+ };
+
+ useEffect(() => {
+ fetchHistories();
+ }, []);
+
+ const dispatchInitialData = (tabId: string) => {
+ batch(() => {
+ dispatch(
+ changeQuery({
+ tabId,
+ query: {
+ [RAW_QUERY]: searchQuery,
+ [SELECTED_DATE_RANGE]: selectedDateRangeRef.current,
+ [TAB_CREATED_TYPE]: NEW_TAB,
+ },
+ })
+ );
+ dispatch(setSelectedQueryTab({ tabId }));
+ });
+ };
+
+ const handleQuerySearch = async () => {
+ const emptyTabId = getExistingEmptyTab({
+ tabIds: tabIdsRef.current,
+ queries: queryRef.current,
+ explorerData: explorerDataRef.current,
+ });
+ const newTabId = emptyTabId ? emptyTabId : await addNewTab();
+
+ // update this new tab with data
+ await dispatchInitialData(newTabId);
+
+ // redirect to explorer
+ history.push('/event_analytics/explorer');
+ };
+
+ const handleQueryChange = async (query: string) => setSearchQuery(query);
+
+ const handleTimePickerChange = async (timeRange: string[]) => setSelectedDateRange(timeRange);
+
+ const handleHistoryClick = async (objectId: string) => {
+ const emptyTabId = getExistingEmptyTab({
+ tabIds: tabIdsRef.current,
+ queries: queryRef.current,
+ explorerData: explorerDataRef.current,
+ });
+ const newTabId = emptyTabId ? emptyTabId : await addNewTab();
+ batch(() => {
+ dispatch(
+ changeQuery({
+ tabId: newTabId,
+ query: {
+ [TAB_CREATED_TYPE]: REDIRECT_TAB,
+ },
+ })
+ );
+ dispatch(setSelectedQueryTab({ tabId: newTabId }));
+ });
+ // redirect to explorer
+ history.push(`/event_analytics/explorer/${objectId}`);
+ };
+
+ const addSampledata = async () => {
+ setModalLayout(
+ getSampleDataModal(closeModal, async () => {
+ closeModal();
+ await addSampleEvents();
+ })
+ );
+ showModal();
+ };
+
+ const addSampleEvents = async () => {
+ try {
+ setIsTableLoading(true);
+ const flights = await http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_flights',
+ },
+ })
+ .then((resp: any) => resp.total === 0);
+ const logs = await http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_logs',
+ },
+ })
+ .then((resp: any) => resp.total === 0);
+ if (flights || logs) setToast('Adding sample data. This can take some time.');
+ await Promise.all([
+ flights ? http.post('../api/sample_data/flights') : Promise.resolve(),
+ logs ? http.post('../api/sample_data/logs') : Promise.resolve(),
+ ]);
+
+ await http
+ .get(
+ `${OBSERVABILITY_BASE}${EVENT_ANALYTICS}${SAVED_OBJECTS}/addSampleSavedObjects/event_analytics`
+ )
+ .then(async (resp: any) => {
+ await http.post(`${CUSTOM_PANELS_API_PREFIX}/panels/addSamplePanels`, {
+ body: JSON.stringify({
+ savedVisualizationIds: [...resp?.savedVizIds],
+ }),
+ });
+
+ const res = await savedObjects.fetchSavedObjects({
+ objectIdList: [...resp?.savedVizIds, ...resp?.savedQueryIds] || [],
+ objectType: ['savedQuery', 'savedVisualization'],
+ sortOrder: 'desc',
+ fromIndex: 0,
+ });
+ setSavedHistories((staleHistoryList) => {
+ return [...res.observabilityObjectList, ...staleHistoryList];
+ });
+ });
+ setToast(`Sample events added successfully.`);
+ } catch (error: any) {
+ setToast(`Cannot add sample events data, error: ${error}`, 'danger');
+ console.error(error.body.message);
+ } finally {
+ setIsTableLoading(false);
+ }
+ };
+
+ const popoverButton = (
+ setIsActionsPopoverOpen(!isActionsPopoverOpen)}
+ data-test-subj="eventHomeAction"
+ >
+ Actions
+
+ );
+
+ const deleteHistory = () => {
+ const customPanelString = `${selectedHistories.length > 1 ? 'histories' : 'history'}`;
+ setModalLayout(
+
+ );
+ showModal();
+ };
+
+ const popoverItems: ReactElement[] = [
+ {
+ setIsActionsPopoverOpen(false);
+ deleteHistory();
+ }}
+ data-test-subj="eventHomeAction__delete"
+ >
+ Delete
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ history.push(`/event_analytics/explorer`);
+ }}
+ data-test-subj="eventHomeAction__explorer"
+ >
+ Event Explorer
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ addSampledata();
+ }}
+ data-test-subj="eventHomeAction__addSamples"
+ >
+ Add samples
+ ,
+ ];
+
+ return (
+ <>
+
+
+
+
+
+ Event analytics
+
+
+
+
+
+
+ {}}
+ setEndTime={() => {}}
+ showSaveButton={false}
+ runButtonText="New Query"
+ getSuggestions={parseGetSuggestions}
+ onItemSelect={onItemSelect}
+ />
+
+
+
+
+
+
+
+
+
+
+ Queries and Visualizations
+ ({savedHistories.length})
+
+
+
+
+ Use Events Analytics to monitor, correlate, analyze and visualize machine
+ generated data through Piped Processing Language. Save frequently searched queries
+ and visualizations for quick access{' '}
+
+ Learn more
+
+
+
+
+
+
+ setIsActionsPopoverOpen(false)}
+ >
+
+
+
+
+
+
+
+
+
+ {savedHistories.length > 0 ? (
+
+ ) : (
+ <>
+
+
+ No Queries or Visualizations
+
+
+ Use events analytics to create and save frequently searched
+
+ queries and visualizations, using PPL.
+
+
+
+
+
+ history.push(`/event_analytics/explorer`)}
+ data-test-subj="actionEventExplorer"
+ >
+ Event Explorer
+
+
+
+ addSampledata()}
+ data-test-subj="actionAddSamples"
+ >
+ Add samples
+
+
+
+
+ >
+ )}
+
+
+
+
+
+ {isModalVisible && modalLayout}
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/home_table/__tests__/__snapshots__/saved_query_table.test.tsx.snap b/dashboards-observability/public/components/explorer/home_table/__tests__/__snapshots__/saved_query_table.test.tsx.snap
new file mode 100644
index 000000000..fa0ee7e42
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/home_table/__tests__/__snapshots__/saved_query_table.test.tsx.snap
@@ -0,0 +1,1686 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Saved query table component Renders saved query table 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="field_value_selection_0"
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="euiFilterGroup__popoverPanel"
+ panelPaddingSize="none"
+ withTitle={false}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select all rows
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+
+
+
+ Type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+ Mock Flight count by destination save to panel
+
+
+
+
+
+
+
+
+ Type
+
+
+
+ Visualization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+ Mock Flight count by destination
+
+
+
+
+
+
+
+
+ Type
+
+
+
+ Visualization
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :
+ 10
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rows per page
+
+ :
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/home_table/__tests__/saved_query_table.test.tsx b/dashboards-observability/public/components/explorer/home_table/__tests__/saved_query_table.test.tsx
new file mode 100644
index 000000000..c8e4eee8b
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/home_table/__tests__/saved_query_table.test.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { SavedQueryTable } from '../saved_query_table';
+import { SAVED_HISTORIES } from '../../../../../test/event_analytics_constants';
+
+describe('Saved query table component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders saved query table', async () => {
+ const handleHistoryClick = jest.fn();
+ const handleSelectHistory = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/home_table/saved_query_table.tsx b/dashboards-observability/public/components/explorer/home_table/saved_query_table.tsx
new file mode 100644
index 000000000..0588232a5
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/home_table/saved_query_table.tsx
@@ -0,0 +1,150 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useRef } from 'react';
+import { EuiLink, EuiInMemoryTable, EuiIcon } from '@elastic/eui';
+import { FILTER_OPTIONS } from '../../../../common/constants/explorer';
+
+interface savedQueryTableProps {
+ savedHistories: Array;
+ handleHistoryClick: (objectId: string) => void;
+ handleSelectHistory: (selectedHistories: Array) => void;
+ isTableLoading: boolean;
+ selectedHistories: Array;
+}
+
+export function SavedQueryTable({
+ savedHistories,
+ handleHistoryClick,
+ handleSelectHistory,
+ isTableLoading,
+}: savedQueryTableProps) {
+ const [pageIndex, setPageIndex] = useState(0);
+ const [pageSize, setPageSize] = useState(10);
+ const pageIndexRef = useRef();
+ pageIndexRef.current = pageIndex;
+ const pageSizeRef = useRef();
+ pageSizeRef.current = pageSize;
+
+ const onTableChange = ({ page = {} }) => {
+ const { index: pageIndex, size: pageSize } = page;
+
+ setPageIndex(pageIndex);
+ setPageSize(pageSize);
+ };
+
+ const columns = [
+ {
+ field: 'type',
+ name: '',
+ sortable: true,
+ width: '40px',
+ render: (item: any) => {
+ if (item == 'Visualization') {
+ return (
+
+
+
+ );
+ } else {
+ return (
+
+
+
+ );
+ }
+ },
+ },
+ {
+ field: 'data',
+ name: 'Name',
+ width: '70%',
+ sortable: true,
+ truncateText: true,
+ render: (item: any) => {
+ return (
+ {
+ handleHistoryClick(item.objectId);
+ }}
+ data-test-subj="eventHome__savedQueryTableName"
+ >
+ {item.name}
+
+ );
+ },
+ },
+ {
+ field: 'type',
+ name: 'Type',
+ },
+ ];
+
+ const histories = savedHistories.map((h) => {
+ const isSavedVisualization = h.hasOwnProperty('savedVisualization');
+ const savedObject = isSavedVisualization ? h.savedVisualization : h.savedQuery;
+ const curType = isSavedVisualization ? 'savedVisualization' : 'savedQuery';
+ const record = {
+ objectId: h.objectId,
+ objectType: curType,
+ name: savedObject.name,
+ query: savedObject.query,
+ date_start: savedObject.selected_date_range.start,
+ date_end: savedObject.selected_date_range.end,
+ timestamp: savedObject.selected_timestamp?.name,
+ fields: savedObject.selected_fields?.tokens || [],
+ };
+ return {
+ id: h.objectId,
+ data: record,
+ name: savedObject.name,
+ type: isSavedVisualization ? 'Visualization' : 'Query',
+ };
+ });
+
+ const search = {
+ box: {
+ incremental: true,
+ },
+ filters: [
+ {
+ type: 'field_value_selection',
+ field: 'type',
+ name: 'Type',
+ multiSelect: false,
+ options: FILTER_OPTIONS.map((i) => ({
+ value: i,
+ name: i,
+ view: i,
+ })),
+ },
+ ],
+ };
+
+ const pagination = {
+ pageIndex,
+ pageSize,
+ totalItemCount: histories.length,
+ pageSizeOptions: [5, 10, 20, 50],
+ };
+
+ return (
+ {
+ handleSelectHistory(selectedHistories);
+ },
+ }}
+ />
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/hooks/index.ts b/dashboards-observability/public/components/explorer/hooks/index.ts
new file mode 100644
index 000000000..68b898f14
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hooks/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { useFetchEvents } from './use_fetch_events';
+export { useFetchVisualizations } from './use_fetch_visualizations';
+export { TabContext } from './use_tab_context';
diff --git a/dashboards-observability/public/components/explorer/hooks/use_fetch_events.ts b/dashboards-observability/public/components/explorer/hooks/use_fetch_events.ts
new file mode 100644
index 000000000..8abd87c99
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hooks/use_fetch_events.ts
@@ -0,0 +1,229 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { useState, useRef } from 'react';
+import { batch } from 'react-redux';
+import { isEmpty } from 'lodash';
+import { useDispatch, useSelector } from 'react-redux';
+import { IField } from 'common/types/explorer';
+import {
+ FINAL_QUERY,
+ SELECTED_FIELDS,
+ UNSELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ QUERIED_FIELDS,
+} from '../../../../common/constants/explorer';
+import { fetchSuccess, reset as queryResultReset } from '../slices/query_result_slice';
+import { selectQueries } from '../slices/query_slice';
+import { reset as visualizationReset } from '../slices/visualization_slice';
+import { updateFields, sortFields, selectFields } from '../slices/field_slice';
+import PPLService from '../../../services/requests/ppl';
+
+interface IFetchEventsParams {
+ pplService: PPLService;
+ requestParams: { tabId: string };
+}
+
+export const useFetchEvents = ({ pplService, requestParams }: IFetchEventsParams) => {
+ const dispatch = useDispatch();
+ const [isEventsLoading, setIsEventsLoading] = useState(false);
+ const queries = useSelector(selectQueries);
+ const fields = useSelector(selectFields);
+ const [response, setResponse] = useState();
+ const queriesRef = useRef();
+ const fieldsRef = useRef();
+ const responseRef = useRef();
+ queriesRef.current = queries;
+ fieldsRef.current = fields;
+ responseRef.current = response;
+
+ const fetchEvents = async (
+ { query }: { query: string },
+ format: string,
+ handler: (res: any) => void,
+ errorHandler?: (error: any) => void
+ ) => {
+ setIsEventsLoading(true);
+ await pplService
+ .fetch(
+ {
+ query,
+ format,
+ },
+ errorHandler
+ )
+ .then((res: any) => {
+ handler(res);
+ })
+ .catch((err: any) => {
+ console.error(err);
+ })
+ .finally(() => {
+ setIsEventsLoading(false);
+ });
+ };
+
+ const dispatchOnGettingHis = (res: any) => {
+ const selectedFields: Array = fieldsRef.current![requestParams.tabId][
+ SELECTED_FIELDS
+ ].map((field: IField) => field.name);
+ setResponse(res);
+ batch(() => {
+ dispatch(
+ queryResultReset({
+ tabId: requestParams.tabId,
+ })
+ );
+ dispatch(
+ fetchSuccess({
+ tabId: requestParams.tabId,
+ data: {
+ ...res,
+ },
+ })
+ );
+ dispatch(
+ updateFields({
+ tabId: requestParams.tabId,
+ data: {
+ [UNSELECTED_FIELDS]: res?.schema ? [...res.schema] : [],
+ [QUERIED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: res?.schema
+ ? isEmpty(selectedFields)
+ ? [...res.schema]
+ : [
+ ...res?.schema.filter(
+ (curField: IField) => !selectedFields.includes(curField.name)
+ ),
+ ]
+ : [],
+ },
+ })
+ );
+ dispatch(
+ sortFields({
+ tabId: requestParams.tabId,
+ data: [AVAILABLE_FIELDS, UNSELECTED_FIELDS],
+ })
+ );
+ dispatch(
+ visualizationReset({
+ tabId: requestParams.tabId,
+ })
+ );
+ });
+ };
+
+ const dispatchOnNoHis = (res: any) => {
+ setResponse(res);
+ batch(() => {
+ dispatch(
+ queryResultReset({
+ tabId: requestParams.tabId,
+ })
+ );
+ dispatch(
+ updateFields({
+ tabId: requestParams.tabId,
+ data: {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [QUERIED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: res?.schema ? [...res.schema] : [],
+ },
+ })
+ );
+ dispatch(
+ sortFields({
+ tabId: requestParams.tabId,
+ data: [AVAILABLE_FIELDS],
+ })
+ );
+ dispatch(
+ visualizationReset({
+ tabId: requestParams.tabId,
+ })
+ );
+ });
+ };
+
+ const getLiveTail = (query: string = '', errorHandler?: (error: any) => void) => {
+ const cur = queriesRef.current;
+ const searchQuery = isEmpty(query) ? cur![requestParams.tabId][FINAL_QUERY] : query;
+ fetchEvents(
+ { query: searchQuery },
+ 'jdbc',
+ (res: any) => {
+ if (!isEmpty(res.jsonData)) {
+ if (!isEmpty(responseRef.current)) {
+ res.jsonData = res.jsonData.concat(responseRef.current.jsonData);
+ res.datarows = res.datarows.concat(responseRef.current.datarows);
+ res.total = res.total + responseRef.current.total;
+ res.size = res.size + responseRef.current.size;
+ }
+ dispatchOnGettingHis(res);
+ }
+ if (isEmpty(res.jsonData) && isEmpty(responseRef.current)) {
+ dispatchOnNoHis(res);
+ }
+ },
+ errorHandler
+ );
+ };
+
+ const getEvents = (query: string = '', errorHandler?: (error: any) => void) => {
+ const cur = queriesRef.current;
+ const searchQuery = isEmpty(query) ? cur![requestParams.tabId][FINAL_QUERY] : query;
+ fetchEvents(
+ { query: searchQuery },
+ 'jdbc',
+ (res: any) => {
+ if (!isEmpty(res.jsonData)) {
+ return dispatchOnGettingHis(res);
+ }
+ // when no hits and needs to get available fields to override default timestamp
+ dispatchOnNoHis(res);
+ },
+ errorHandler
+ );
+ };
+
+ const getAvailableFields = (query: string) => {
+ fetchEvents({ query }, 'jdbc', (res: any) => {
+ batch(() => {
+ dispatch(
+ fetchSuccess({
+ tabId: requestParams.tabId,
+ data: {
+ jsonDataAll: res.jsonData,
+ },
+ })
+ );
+ dispatch(
+ updateFields({
+ tabId: requestParams.tabId,
+ data: {
+ [AVAILABLE_FIELDS]: res?.schema ? [...res.schema] : [],
+ },
+ })
+ );
+ dispatch(
+ sortFields({
+ tabId: requestParams.tabId,
+ data: [AVAILABLE_FIELDS, UNSELECTED_FIELDS],
+ })
+ );
+ });
+ });
+ };
+
+ return {
+ isEventsLoading,
+ getLiveTail,
+ getEvents,
+ getAvailableFields,
+ fetchEvents,
+ };
+};
diff --git a/dashboards-observability/public/components/explorer/hooks/use_fetch_visualizations.ts b/dashboards-observability/public/components/explorer/hooks/use_fetch_visualizations.ts
new file mode 100644
index 000000000..c60492c8c
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hooks/use_fetch_visualizations.ts
@@ -0,0 +1,130 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { useState, useRef } from 'react';
+import { batch, useDispatch, useSelector } from 'react-redux';
+import {
+ FINAL_QUERY,
+ QUERIED_FIELDS,
+ RAW_QUERY,
+ SELECTED_FIELDS,
+ SELECTED_TIMESTAMP,
+} from '../../../../common/constants/explorer';
+import { render as renderCountDis } from '../slices/count_distribution_slice';
+import { selectQueries } from '../slices/query_slice';
+import { render as renderExplorerVis } from '../slices/visualization_slice';
+import { updateFields, sortFields } from '../slices/field_slice';
+import PPLService from '../../../services/requests/ppl';
+import { fetchSuccess } from '../slices/query_result_slice';
+
+interface IFetchVisualizationsParams {
+ pplService: PPLService;
+ requestParams: { tabId: string };
+}
+
+export const useFetchVisualizations = ({
+ pplService,
+ requestParams,
+}: IFetchVisualizationsParams) => {
+ const dispatch = useDispatch();
+ const [isVisLoading, setIsVisLoading] = useState(false);
+ const queries = useSelector(selectQueries);
+ const queriesRef = useRef();
+ queriesRef.current = queries;
+
+ const fetchVisualizations = async (
+ { query }: { query: string },
+ format: string,
+ handler: (res: any) => void
+ ) => {
+ setIsVisLoading(true);
+
+ await pplService
+ .fetch({
+ query,
+ format,
+ })
+ .then((res: any) => {
+ handler(res);
+ })
+ .catch((err: any) => {
+ console.error(err);
+ })
+ .finally(() => {
+ setIsVisLoading(false);
+ });
+ };
+
+ const getCountVisualizations = (interval: string) => {
+ const cur = queriesRef.current;
+ const rawQuery = cur![requestParams.tabId][FINAL_QUERY];
+ fetchVisualizations(
+ {
+ query: `${rawQuery} | stats count() by span(${
+ cur![requestParams.tabId][SELECTED_TIMESTAMP]
+ }, 1${(interval = interval ? interval : 'm')})`,
+ },
+ 'viz',
+ (res: any) => {
+ dispatch(
+ renderCountDis({
+ tabId: requestParams.tabId,
+ data: res,
+ })
+ );
+ }
+ );
+ };
+
+ const getVisualizations = () => {
+ const cur = queriesRef.current;
+ const rawQuery = cur![requestParams.tabId][FINAL_QUERY];
+ fetchVisualizations(
+ {
+ query: rawQuery,
+ },
+ 'viz',
+ (res: any) => {
+ batch(() => {
+ dispatch(
+ renderExplorerVis({
+ tabId: requestParams.tabId,
+ data: res,
+ })
+ );
+ dispatch(
+ fetchSuccess({
+ tabId: requestParams.tabId,
+ data: {
+ jsonData: res?.jsonData || {},
+ },
+ })
+ );
+ dispatch(
+ updateFields({
+ tabId: requestParams.tabId,
+ data: {
+ [QUERIED_FIELDS]: res?.metadata?.fields || [],
+ [SELECTED_FIELDS]: [],
+ },
+ })
+ );
+ dispatch(
+ sortFields({
+ tabId: requestParams.tabId,
+ data: [QUERIED_FIELDS],
+ })
+ );
+ });
+ }
+ );
+ };
+
+ return {
+ isVisLoading,
+ getVisualizations,
+ getCountVisualizations,
+ };
+};
diff --git a/dashboards-observability/public/components/explorer/hooks/use_tab_context.ts b/dashboards-observability/public/components/explorer/hooks/use_tab_context.ts
new file mode 100644
index 000000000..32e9902c3
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/hooks/use_tab_context.ts
@@ -0,0 +1,3 @@
+import { createContext } from 'react';
+
+export const TabContext = createContext({});
diff --git a/dashboards-observability/public/components/explorer/log_explorer.scss b/dashboards-observability/public/components/explorer/log_explorer.scss
new file mode 100644
index 000000000..772a5b873
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/log_explorer.scss
@@ -0,0 +1,35 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.queryTabs {
+ .euiTabs {
+ .tab-title {
+ max-width: 8rem;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ svg {
+ vertical-align: inherit;
+ }
+ .linkNewTag{
+ display: inline-block;
+ text-align: center;
+ font-size: 0.875rem;
+ line-height: 3.5;
+ padding: 0.5rem;
+ min-width: 6rem;
+ }
+ }
+}
+
+.tab-title {
+ display: inline-block;
+ margin-right: 5px;
+}
+
+.search-area {
+ position: relative;
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/log_explorer.tsx b/dashboards-observability/public/components/explorer/log_explorer.tsx
new file mode 100644
index 000000000..dd10d70a7
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/log_explorer.tsx
@@ -0,0 +1,217 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import './log_explorer.scss';
+import React, { useEffect, useMemo, useRef, useState } from 'react';
+import { useDispatch, useSelector, batch } from 'react-redux';
+import { uniqueId, map, isEmpty } from 'lodash';
+import $ from 'jquery';
+import { EuiIcon, EuiText, EuiTabbedContentTab, EuiTabbedContent } from '@elastic/eui';
+import { Explorer } from './explorer';
+import { ILogExplorerProps } from '../../../common/types/explorer';
+import {
+ TAB_TITLE,
+ TAB_ID_TXT_PFX,
+ SAVED_OBJECT_ID,
+ NEW_TAB,
+ REDIRECT_TAB,
+ TAB_EVENT_ID,
+ TAB_CHART_ID,
+ APP_ANALYTICS_TAB_ID_REGEX,
+} from '../../../common/constants/explorer';
+import { selectQueryTabs, setSelectedQueryTab } from './slices/query_tab_slice';
+import { selectQueries } from './slices/query_slice';
+import { selectQueryResult } from './slices/query_result_slice';
+import { initializeTabData, removeTabData } from '../application_analytics/helpers/utils';
+
+const searchBarConfigs = {
+ [TAB_EVENT_ID]: {
+ showSaveButton: true,
+ showSavePanelOptionsList: false,
+ },
+ [TAB_CHART_ID]: {
+ showSaveButton: true,
+ showSavePanelOptionsList: true,
+ },
+};
+
+export const LogExplorer = ({
+ pplService,
+ dslService,
+ savedObjects,
+ timestampUtils,
+ setToast,
+ savedObjectId,
+ getExistingEmptyTab,
+ history,
+ notifications,
+ http,
+}: ILogExplorerProps) => {
+ const dispatch = useDispatch();
+ const tabIds = useSelector(selectQueryTabs).queryTabIds.filter(
+ (tabid: string) => !tabid.match(APP_ANALYTICS_TAB_ID_REGEX)
+ );
+ const tabNames = useSelector(selectQueryTabs).tabNames;
+ const queries = useSelector(selectQueries);
+ const curSelectedTabId = useSelector(selectQueryTabs).selectedQueryTab;
+ const explorerData = useSelector(selectQueryResult);
+ const queryRef = useRef();
+ const tabIdsRef = useRef();
+ const explorerDataRef = useRef();
+ const curSelectedTabIdRef = useRef();
+ queryRef.current = queries;
+ tabIdsRef.current = tabIds;
+ explorerDataRef.current = explorerData;
+ curSelectedTabIdRef.current = curSelectedTabId;
+
+ const [tabCreatedTypes, setTabCreatedTypes] = useState({});
+
+ // Append add-new-tab link to the end of the tab list, and remove it once tabs state changes
+ useEffect(() => {
+ const newLink = $(
+ '+ Add new '
+ ).on('click', () => {
+ addNewTab(NEW_TAB);
+ });
+ $('.queryTabs > .euiTabs').append(newLink);
+ return () => {
+ $('.queryTabs > .euiTabs .linkNewTag').remove();
+ };
+ }, [tabIds]);
+
+ const handleTabClick = (selectedTab: EuiTabbedContentTab) => {
+ history.replace(
+ `/event_analytics/explorer/${queryRef.current![selectedTab.id][SAVED_OBJECT_ID] || ''}`
+ );
+ dispatch(setSelectedQueryTab({ tabId: selectedTab.id }));
+ };
+
+ const handleTabClose = (TabIdToBeClosed: string) => {
+ if (tabIds.length === 1) {
+ setToast('Cannot close last tab.', 'danger');
+ return;
+ }
+
+ const index: number = tabIds.indexOf(TabIdToBeClosed);
+ const curSelectedTab = curSelectedTabIdRef.current;
+ let newIdToFocus = '';
+ if (TabIdToBeClosed === curSelectedTab) {
+ if (index === 0) {
+ newIdToFocus = tabIds[index + 1];
+ } else if (index > 0) {
+ newIdToFocus = tabIds[index - 1];
+ }
+ }
+ removeTabData(dispatch, TabIdToBeClosed, newIdToFocus);
+ };
+
+ const addNewTab = async (where: string) => {
+ // get a new tabId
+ const tabId = uniqueId(TAB_ID_TXT_PFX);
+
+ // create a new tab
+ await initializeTabData(dispatch, tabId, where);
+
+ setTabCreatedTypes((staleState) => {
+ return {
+ ...staleState,
+ [tabId]: where,
+ };
+ });
+
+ return tabId;
+ };
+
+ const dispatchSavedObjectId = async () => {
+ const emptyTabId = getExistingEmptyTab({
+ tabIds: tabIdsRef.current,
+ queries: queryRef.current,
+ explorerData: explorerDataRef.current,
+ });
+ const newTabId = emptyTabId ? emptyTabId : await addNewTab(REDIRECT_TAB);
+ return newTabId;
+ };
+
+ useEffect(() => {
+ if (!isEmpty(savedObjectId)) {
+ dispatchSavedObjectId();
+ }
+ }, []);
+
+ function getQueryTab({
+ tabTitle,
+ tabId,
+ handlesTabClose,
+ }: {
+ tabTitle: string;
+ tabId: string;
+ handlesTabClose: (TabIdToBeClosed: string) => void;
+ }) {
+ return {
+ id: tabId,
+ name: (
+ <>
+
+ {tabTitle}
+ {
+ e.stopPropagation();
+ handlesTabClose(tabId);
+ }}
+ data-test-subj="eventExplorer__tabClose"
+ />
+
+ >
+ ),
+ content: (
+ <>
+
+ >
+ ),
+ };
+ }
+
+ const memorizedTabs = useMemo(() => {
+ const res = map(tabIds, (tabId) => {
+ return getQueryTab({
+ tabTitle: tabNames[tabId] || TAB_TITLE,
+ tabId,
+ handlesTabClose: handleTabClose,
+ });
+ });
+
+ return res;
+ }, [tabIds, tabNames, tabCreatedTypes]);
+
+ return (
+ <>
+ tab.id === curSelectedTabId)}
+ onTabClick={(selectedTab: EuiTabbedContentTab) => handleTabClick(selectedTab)}
+ data-test-subj="eventExplorer__topLevelTabbing"
+ />
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/no_results.tsx b/dashboards-observability/public/components/explorer/no_results.tsx
new file mode 100644
index 000000000..802099729
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/no_results.tsx
@@ -0,0 +1,52 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
+import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
+
+export const NoResults = () => {
+ return (
+
+ <>
+
+
+
+
+
+ }
+ color="warning"
+ iconType="help"
+ data-test-subj="discoverNoResults"
+ />
+ <>
+
+
+
+
+
+
+
+
+
+ >
+
+
+ >
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/reducers/fetch_reducers.ts b/dashboards-observability/public/components/explorer/reducers/fetch_reducers.ts
new file mode 100644
index 000000000..6853cee58
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/reducers/fetch_reducers.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const fetchSuccess = (state, { payload }) => {
+ state[payload.tabId] = {
+ ...state[payload.tabId],
+ ...payload.data
+ };
+};
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/reducers/index.ts b/dashboards-observability/public/components/explorer/reducers/index.ts
new file mode 100644
index 000000000..9bdf29121
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/reducers/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { fetchSuccess } from './fetch_reducers';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/reducers/query_reducers.ts b/dashboards-observability/public/components/explorer/reducers/query_reducers.ts
new file mode 100644
index 000000000..bd4273e73
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/reducers/query_reducers.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export const queryChange = (state = {}, action) => {
+ return {
+ ...action.payload
+ };
+};
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap b/dashboards-observability/public/components/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap
new file mode 100644
index 000000000..6344e67ec
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/save_panel/__tests__/__snapshots__/save_panel.test.tsx.snap
@@ -0,0 +1,695 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Saved query table component Renders saved query table 1`] = `
+
+
+
+ Custom operational dashboards/application
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Logs] Web traffic Panel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Logs] Web traffic Panel 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Search existing dashboards or applications by name
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+
+
+
+
+
+
+
+ Name for your savings
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/save_panel/__tests__/save_panel.test.tsx b/dashboards-observability/public/components/explorer/save_panel/__tests__/save_panel.test.tsx
new file mode 100644
index 000000000..8a907ac2a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/save_panel/__tests__/save_panel.test.tsx
@@ -0,0 +1,40 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { SavePanel } from '../save_panel';
+import { SELECTED_PANELS_OPTIONS } from '../../../../../test/event_analytics_constants';
+import SavedObjects from '../../../../services/saved_objects/event_analytics/saved_objects';
+import httpClientMock from '../../../../../test/__mocks__/httpClientMock';
+
+describe('Saved query table component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders saved query table', async () => {
+ const handleNameChange = jest.fn();
+ const handleOptionChange = jest.fn();
+ const savedObjects = new SavedObjects(httpClientMock);
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/save_panel/index.ts b/dashboards-observability/public/components/explorer/save_panel/index.ts
new file mode 100644
index 000000000..de81603f7
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/save_panel/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { SavePanel } from './save_panel';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/save_panel/save_panel.tsx b/dashboards-observability/public/components/explorer/save_panel/save_panel.tsx
new file mode 100644
index 000000000..e18022db5
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/save_panel/save_panel.tsx
@@ -0,0 +1,95 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { EuiTitle, EuiComboBox, EuiFormRow, EuiSpacer, EuiFieldText } from '@elastic/eui';
+import { useEffect } from 'react';
+import { isEmpty } from 'lodash';
+import SavedObjects from '../../../services/saved_objects/event_analytics/saved_objects';
+
+interface ISavedPanelProps {
+ selectedOptions: any;
+ handleNameChange: any;
+ handleOptionChange: any;
+ savedObjects: SavedObjects;
+ savePanelName: string;
+ showOptionList: boolean;
+}
+
+interface CustomPanelOptions {
+ id: string;
+ name: string;
+ dateCreated: string;
+ dateModified: string;
+}
+
+export const SavePanel = ({
+ selectedOptions,
+ handleNameChange,
+ handleOptionChange,
+ savedObjects,
+ savePanelName,
+ showOptionList,
+}: ISavedPanelProps) => {
+ const [options, setOptions] = useState([]);
+
+ const getCustomPabnelList = async (savedObjects: SavedObjects) => {
+ const optionRes = await savedObjects
+ .fetchCustomPanels()
+ .then((res: any) => {
+ return res;
+ })
+ .catch((error: any) => console.error(error));
+ setOptions(optionRes?.panels || []);
+ };
+
+ useEffect(() => {
+ getCustomPabnelList(savedObjects);
+ }, []);
+
+ return (
+ <>
+ {showOptionList && (
+ <>
+
+ {'Custom operational dashboards/application'}
+
+
+ {
+ handleOptionChange(options);
+ }}
+ selectedOptions={selectedOptions}
+ options={options.map((option: CustomPanelOptions) => {
+ return {
+ panel: option,
+ label: option.name,
+ };
+ })}
+ isClearable={true}
+ data-test-subj="eventExplorer__querySaveComboBox"
+ />
+
+ >
+ )}
+
+ Name
+
+
+ {
+ handleNameChange(e.target.value);
+ }}
+ data-test-subj="eventExplorer__querySaveName"
+ />
+
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap b/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap
new file mode 100644
index 000000000..44f6114c2
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/field.test.tsx.snap
@@ -0,0 +1,296 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Field component Renders a sidebar field 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap b/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap
new file mode 100644
index 000000000..2b5fa4647
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/__tests__/__snapshots__/sidebar.test.tsx.snap
@@ -0,0 +1,8651 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Siderbar component Renders empty sidebar component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Siderbar component Renders sidebar component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Query fields
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ double_per_ip_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ double_per_ip_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ double_per_ip_bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ host
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ ip_count
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ ip_count
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ip_count
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ per_ip_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ per_ip_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ per_ip_bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ resp_code
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ resp_code
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ resp_code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ sum_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ sum_bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sum_bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Selected Fields
+
+
+
+
+
+
+
+
+
+
+
+ Available Fields
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clientip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ event
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ extension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ geo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ host
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ machine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ memory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ message
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ phpmemory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ referer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ response
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default Timestamp
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+ Default Timestamp
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ timestamp
+
+
+
+
+
+
+
+
+ Default Timestamp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Override
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ />
+ }
+ closePopover={[Function]}
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+ Override
+
+
+
+
+
+
+
+
+
+ }
+ fieldIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ size="s"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ utc_time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/sidebar/__tests__/field.test.tsx b/dashboards-observability/public/components/explorer/sidebar/__tests__/field.test.tsx
new file mode 100644
index 000000000..c6660d934
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/__tests__/field.test.tsx
@@ -0,0 +1,41 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { Field } from '../field';
+import { AGENT_FIELD } from '../../../../../test/event_analytics_constants';
+
+describe('Field component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders a sidebar field', async () => {
+ const onToggleField = jest.fn();
+ const handleOverrideTimestamp = jest.fn();
+ const selectedTimestamp = 'timestamp';
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/sidebar/__tests__/sidebar.test.tsx b/dashboards-observability/public/components/explorer/sidebar/__tests__/sidebar.test.tsx
new file mode 100644
index 000000000..0e8e23ec4
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/__tests__/sidebar.test.tsx
@@ -0,0 +1,93 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { Sidebar } from '../sidebar';
+import {
+ SELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ UNSELECTED_FIELDS,
+ QUERIED_FIELDS
+} from '../../../../../common/constants/explorer';
+import {
+ AVAILABLE_FIELDS as SIDEBAR_AVAILABLE_FIELDS,
+ QUERY_FIELDS,
+ JSON_DATA,
+ JSON_DATA_ALL
+} from '../../../../../test/event_analytics_constants';
+
+describe('Siderbar component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders empty sidebar component', async () => {
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [QUERIED_FIELDS]: []
+ };
+ const handleAddField = jest.fn();
+ const handleOverrideTimestamp = jest.fn();
+ const selectedTimestamp = 'timestamp';
+ const explorerData = {};
+ const handleRemoveField = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('Renders sidebar component', async () => {
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS,
+ [QUERIED_FIELDS]: QUERY_FIELDS
+ };
+ const handleAddField = jest.fn();
+ const handleOverrideTimestamp = jest.fn();
+ const selectedTimestamp = 'timestamp';
+ const explorerData = {
+ 'jsonData': JSON_DATA,
+ 'jsonDataAll': JSON_DATA_ALL
+ };
+ const handleRemoveField = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/sidebar/field.tsx b/dashboards-observability/public/components/explorer/sidebar/field.tsx
new file mode 100644
index 000000000..3b6b127ae
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/field.tsx
@@ -0,0 +1,184 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import { i18n } from '@osd/i18n';
+import { isEqual, toUpper, upperFirst } from 'lodash';
+import {
+ EuiPopover,
+ EuiButtonIcon,
+ EuiToolTip,
+ EuiButton,
+ EuiMark,
+ EuiLoadingSpinner,
+ EuiPopoverTitle,
+ EuiPanel,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiTitle,
+} from '@elastic/eui';
+import { FieldButton } from '../../common/field_button';
+import { FieldIcon } from '../../common/field_icon';
+import { IField } from '../../../../common/types/explorer';
+import { FieldInsights } from './field_insights';
+
+interface IFieldProps {
+ field: IField;
+ selectedTimestamp: string;
+ isOverridingTimestamp: boolean;
+ handleOverrideTimestamp: (timestamp: { name: string; type: string }) => void;
+ selected: boolean;
+ showToggleButton: boolean;
+ showTimestampOverrideButton: boolean;
+ isFieldToggleButtonDisabled: boolean;
+ onToggleField: (field: IField) => void;
+}
+
+export const Field = (props: IFieldProps) => {
+ const {
+ query,
+ field,
+ selectedTimestamp,
+ isOverridingTimestamp,
+ handleOverrideTimestamp,
+ selected,
+ isFieldToggleButtonDisabled = false,
+ showTimestampOverrideButton = true,
+ onToggleField,
+ } = props;
+
+ const [isFieldDetailsOpen, setIsFieldDetailsOpen] = useState(false);
+
+ const addLabelAria = i18n.translate('addButtonAriaLabel', {
+ defaultMessage: 'Add {field} to table',
+ values: { field: field.name },
+ });
+ const removeLabelAria = i18n.translate('removeButtonAriaLabel', {
+ defaultMessage: 'Remove {field} from table',
+ values: { field: field.name },
+ });
+
+ const togglePopover = () => {
+ setIsFieldDetailsOpen((staleState) => !staleState);
+ };
+
+ const toggleField = (field: IField) => {
+ onToggleField(field);
+ };
+
+ const getFieldActionDOM = () => {
+ return (
+ <>
+
+ <>
+ {showTimestampOverrideButton && isEqual(field.type, 'timestamp') ? (
+ isEqual(selectedTimestamp, field.name) ? (
+
+ Default Timestamp
+
+ ) : isOverridingTimestamp ? (
+
+ ) : (
+ handleOverrideTimestamp(field)}
+ data-test-subj="eventExplorer__overrideDefaultTimestamp"
+ >
+ Override
+
+ )
+ ) : null}
+ >
+
+
+ <>
+ {isFieldToggleButtonDisabled ? (
+
+ ) : (
+ ) => {
+ if (e.type === 'click') {
+ e.currentTarget.focus();
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ toggleField(field);
+ }}
+ data-test-subj={`fieldToggle-${field.name}`}
+ aria-label={selected ? removeLabelAria : addLabelAria}
+ />
+ )}
+ >
+
+ >
+ );
+ };
+
+ return (
+ setIsFieldDetailsOpen(false)}
+ anchorPosition="rightUp"
+ panelClassName="dscSidebarItem__fieldPopoverPanel"
+ button={
+ }
+ fieldName={
+
+ {field.name}
+
+ }
+ fieldAction={getFieldActionDOM()}
+ onClick={togglePopover}
+ />
+ }
+ >
+
+
+
+ {toUpper(field.name)}
+
+
+ {upperFirst(field.type)}
+
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/sidebar/field_insights.tsx b/dashboards-observability/public/components/explorer/sidebar/field_insights.tsx
new file mode 100644
index 000000000..fd03ce1f5
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/field_insights.tsx
@@ -0,0 +1,153 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useMemo, useState, useContext, useEffect } from 'react';
+import { indexOf, last } from 'lodash';
+import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiBasicTable } from '@elastic/eui';
+import { getIndexPatternFromRawQuery } from '../../../../common/utils/query_utils';
+import { TabContext } from '../hooks/use_tab_context';
+
+export const FieldInsights = ({ field, query }: any) => {
+ const { pplService } = useContext(TabContext);
+ const { rawQuery } = query;
+ const index = getIndexPatternFromRawQuery(rawQuery);
+ const generalReports = [
+ {
+ id: 'top_values',
+ name: 'Top values',
+ query: `source = ${index} | top 5 ${field.name} | sort - ${field.name}`,
+ format: 'jdbc',
+ },
+ {
+ id: 'rare_values',
+ name: 'Rare values',
+ query: `source = ${index} | rare ${field.name} | sort + ${field.name}`,
+ format: 'jdbc',
+ },
+ ];
+
+ const numericalOnlyReports = [
+ {
+ id: 'average',
+ name: 'Average overtime',
+ query: `source = ${index} | stats avg(${field.name})`,
+ format: 'viz',
+ },
+ {
+ id: 'maximum',
+ name: 'Maximum overtime',
+ query: `source = ${index} | stats max(${field.name})`,
+ format: 'viz',
+ },
+ {
+ id: 'minimum',
+ name: 'Minimum overtime',
+ query: `source = ${index} | stats min(${field.name})`,
+ format: 'viz',
+ },
+ ];
+ const numericalTypes = ['short', 'integer', 'long', 'float', 'double'];
+ const isNumericalField = indexOf(numericalTypes, field.type) > 0;
+ const [curReport, setCurReport] = useState({ ...generalReports[0] });
+ const [reportContent, setReportContent] = useState({});
+
+ const statsInsightsQueries = [
+ {
+ id: 'stats',
+ name: 'Stats',
+ query: `source = ${index} | stats avg(${field.name}), max(${field.name}), min(${field.name})`,
+ format: 'viz',
+ },
+ ];
+
+ const fetchData = async (requests) => {
+ return await Promise.all(
+ requests.map((reqQuery) => {
+ const req = {
+ format: reqQuery.format,
+ query: reqQuery.query,
+ };
+ return getInsights(req);
+ })
+ );
+ };
+
+ useEffect(() => {
+ let requests = [...generalReports];
+ if (isNumericalField) requests = [...requests, ...statsInsightsQueries];
+ fetchData(requests)
+ .then((res) => {
+ // numerical field
+ generalReports.map((report, index) => {
+ if (!res[index]?.jsonData) return;
+ setReportContent((staleState) => {
+ return {
+ ...staleState,
+ [report.id]: res[index]?.jsonData || {},
+ };
+ });
+ });
+ if (res.length > 2) {
+ const statsRes = last(res);
+ if (!statsRes?.metadata) return;
+ numericalOnlyReports.map((rep, index) => {
+ const fieldName = statsRes.metadata?.fields[index]?.name;
+ setReportContent((staleState) => {
+ return {
+ ...staleState,
+ [rep.id]: [{ [field.name]: statsRes.data[fieldName][0] }],
+ };
+ });
+ });
+ }
+ })
+ .catch((error) => console.error(error));
+ }, []);
+
+ const getInsights = async (query: string) => {
+ try {
+ return await pplService.fetch(query);
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ const insightsContent = useMemo(() => {
+ const columns = [
+ {
+ field: field.name,
+ name: field.name,
+ },
+ ];
+ const repItems = reportContent[curReport.id] || [];
+
+ return ;
+ }, [curReport, reportContent, field.name]);
+
+ return (
+
+
+
+ {generalReports.map((report) => {
+ return (
+
+ setCurReport(report)}>{report.name}
+
+ );
+ })}
+ {indexOf(numericalTypes, field.type) > 0 &&
+ numericalOnlyReports.map((report) => {
+ return (
+
+ setCurReport(report)}>{report.name}
+
+ );
+ })}
+
+
+ {insightsContent}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/sidebar/index.ts b/dashboards-observability/public/components/explorer/sidebar/index.ts
new file mode 100644
index 000000000..bfd2e650e
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { Sidebar } from './sidebar';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/sidebar/sidebar.scss b/dashboards-observability/public/components/explorer/sidebar/sidebar.scss
new file mode 100644
index 000000000..8ef4cc875
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/sidebar.scss
@@ -0,0 +1,112 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.dscSidebar__container {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ background-color: transparent;
+ border-right-color: transparent;
+ border-bottom-color: transparent;
+}
+
+.dscIndexPattern__container {
+ display: flex;
+ align-items: center;
+ height: $euiSize * 3;
+ margin-top: -$euiSizeS;
+}
+
+.dscIndexPattern__triggerButton {
+ @include euiTitle('xs');
+ line-height: $euiSizeXXL;
+}
+
+.dscFieldList {
+ list-style: none;
+ margin-bottom: 0;
+}
+
+.dscFieldListHeader {
+ padding: $euiSizeS $euiSizeS 0 $euiSizeS;
+ background-color: lightOrDarkTheme(tint($euiColorPrimary, 90%), $euiColorLightShade);
+}
+
+.dscFieldList--popular {
+ background-color: lightOrDarkTheme(tint($euiColorPrimary, 90%), $euiColorLightShade);
+}
+
+.dscFieldChooser {
+ padding-left: $euiSize;
+}
+
+.dscFieldChooser__toggle {
+ color: $euiColorMediumShade;
+ margin-left: $euiSizeS !important;
+}
+
+.dscSidebarItem {
+ &:hover,
+ &:focus-within,
+ &[class*='-isActive'] {
+ .dscSidebarItem__action {
+ opacity: 1;
+ }
+ }
+}
+
+/**
+ * 1. Only visually hide the action, so that it's still accessible to screen readers.
+ * 2. When tabbed to, this element needs to be visible for keyboard accessibility.
+ */
+.dscSidebarItem__action {
+ opacity: 0; /* 1 */
+ transition: none;
+
+ &:focus {
+ opacity: 1; /* 2 */
+ }
+ font-size: $euiFontSizeXS;
+ padding: 2px 6px !important;
+ height: 22px !important;
+ min-width: auto !important;
+ .euiButton__content {
+ padding: 0 4px;
+ }
+}
+
+.dscFieldSearch {
+ padding: $euiSizeS;
+}
+
+.dscFieldSearch__toggleButton {
+ width: calc(100% - #{$euiSizeS});
+ color: $euiColorPrimary;
+ padding-left: $euiSizeXS;
+ margin-left: $euiSizeXS;
+}
+
+.dscFieldSearch__filterWrapper {
+ flex-grow: 0;
+}
+
+.dscFieldSearch__formWrapper {
+ padding: $euiSizeM;
+}
+
+.dscFieldDetails {
+ color: $euiTextColor;
+ margin-bottom: $euiSizeS;
+}
+
+.dscSidebarItem__fieldPopoverPanel {
+ min-width: 300px;
+ max-width: 600px;
+ max-height: 600px;
+ overflow-y: scroll;
+}
+
+.override_timestamp_loading {
+ vertical-align: middle;
+}
diff --git a/dashboards-observability/public/components/explorer/sidebar/sidebar.tsx b/dashboards-observability/public/components/explorer/sidebar/sidebar.tsx
new file mode 100644
index 000000000..2d520dd4d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/sidebar/sidebar.tsx
@@ -0,0 +1,215 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './sidebar.scss';
+
+import React, { useState } from 'react';
+import { isEmpty } from 'lodash';
+import { EuiTitle, EuiSpacer, EuiButtonIcon, EuiFieldSearch } from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
+import { cssNumber } from 'jquery';
+import { Field } from './field';
+import { IExplorerFields, IField } from '../../../../common/types/explorer';
+
+interface ISidebarProps {
+ query: string;
+ explorerFields: IExplorerFields;
+ explorerData: any;
+ selectedTimestamp: string;
+ isOverridingTimestamp: boolean;
+ isFieldToggleButtonDisabled: boolean;
+ handleOverrideTimestamp: (timestamp: { name: string; type: string }) => void;
+ handleAddField: (field: IField) => void;
+ handleRemoveField: (field: IField) => void;
+}
+
+export const Sidebar = (props: ISidebarProps) => {
+ const {
+ query,
+ explorerFields,
+ explorerData,
+ selectedTimestamp,
+ isOverridingTimestamp,
+ isFieldToggleButtonDisabled,
+ handleOverrideTimestamp,
+ handleAddField,
+ handleRemoveField,
+ } = props;
+
+ const [showFields, setShowFields] = useState(false);
+ const [searchTerm, setSearchTerm] = useState('');
+
+ return (
+
+
+
+
+ {
+ setSearchTerm(e.target.value);
+ }}
+ placeholder="Search field names"
+ value={searchTerm}
+ data-test-subj="eventExplorer__sidebarSearch"
+ />
+
+
+
+ {((explorerData && !isEmpty(explorerData.jsonData) && !isEmpty(explorerFields)) ||
+ !isEmpty(explorerFields.availableFields)) && (
+ <>
+ {explorerFields?.queriedFields && explorerFields.queriedFields?.length > 0 && (
+ <>
+
+
+
+
+
+
+
+ {explorerFields.queriedFields &&
+ explorerFields.queriedFields.map((field) => {
+ return (
+
+
+
+ );
+ })}
+
+ >
+ )}
+
+
+
+
+
+
+
+ {explorerData &&
+ !isEmpty(explorerData.jsonData) &&
+ explorerFields.selectedFields &&
+ explorerFields.selectedFields.map((field) => {
+ return (
+
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+ setShowFields(!showFields)}
+ aria-label={
+ showFields
+ ? i18n.translate(
+ 'discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel',
+ {
+ defaultMessage: 'Hide fields',
+ }
+ )
+ : i18n.translate(
+ 'discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel',
+ {
+ defaultMessage: 'Show fields',
+ }
+ )
+ }
+ />
+
+
+
+ {explorerFields.availableFields &&
+ explorerFields.availableFields
+ .filter((field) => searchTerm === '' || field.name.indexOf(searchTerm) !== -1)
+ .map((field) => {
+ return (
+
+
+
+ );
+ })}
+
+ >
+ )}
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/slices/count_distribution_slice.ts b/dashboards-observability/public/components/explorer/slices/count_distribution_slice.ts
new file mode 100644
index 000000000..ad1331bfa
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/count_distribution_slice.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import { REDUX_EXPL_SLICE_COUNT_DISTRIBUTION } from '../../../../common/constants/explorer';
+
+const initialState = {
+ [initialTabId]: {},
+};
+
+export const countDistributionSlice = createSlice({
+ name: REDUX_EXPL_SLICE_COUNT_DISTRIBUTION,
+ initialState,
+ reducers: {
+ render: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...payload.data,
+ };
+ },
+ },
+ extraReducers: (builder) => {},
+});
+
+export const { render } = countDistributionSlice.actions;
+
+export const selectCountDistribution = (state) => state.countDistribution;
+
+export default countDistributionSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/slices/field_slice.ts b/dashboards-observability/public/components/explorer/slices/field_slice.ts
new file mode 100644
index 000000000..7519d2ef1
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/field_slice.ts
@@ -0,0 +1,69 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { forEach } from 'lodash';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import {
+ SELECTED_FIELDS,
+ UNSELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ QUERIED_FIELDS,
+ REDUX_EXPL_SLICE_FIELDS,
+} from '../../../../common/constants/explorer';
+import { IField } from '../../../../common/types/explorer';
+
+const initialFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: [],
+ [QUERIED_FIELDS]: [],
+};
+
+const initialState = {
+ [initialTabId]: {
+ ...initialFields,
+ },
+};
+
+export const fieldSlice = createSlice({
+ name: REDUX_EXPL_SLICE_FIELDS,
+ initialState,
+ reducers: {
+ init: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...initialFields,
+ };
+ },
+ updateFields: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...state[payload.tabId],
+ ...payload.data,
+ };
+ },
+ reset: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...initialFields,
+ };
+ },
+ remove: (state, { payload }) => {
+ delete state[payload.tabId];
+ },
+ sortFields: (state, { payload }) => {
+ forEach(payload.data, (toSort: string) => {
+ state[payload.tabId][toSort].sort((prev: IField, cur: IField) =>
+ prev.name.localeCompare(cur.name)
+ );
+ });
+ },
+ },
+ extraReducers: (builder) => {},
+});
+
+export const { init, reset, remove, updateFields, sortFields } = fieldSlice.actions;
+
+export const selectFields = (state) => state.fields;
+
+export default fieldSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/slices/query_result_slice.ts b/dashboards-observability/public/components/explorer/slices/query_result_slice.ts
new file mode 100644
index 000000000..2d3369d4a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/query_result_slice.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { fetchSuccess as fetchSuccessReducer } from '../reducers';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import { REDUX_EXPL_SLICE_QUERY_RESULT } from '../../../../common/constants/explorer';
+
+const initialState = {
+ [initialTabId]: {},
+};
+
+export const queryResultSlice = createSlice({
+ name: REDUX_EXPL_SLICE_QUERY_RESULT,
+ initialState,
+ reducers: {
+ fetchSuccess: fetchSuccessReducer,
+ reset: (state, { payload }) => {
+ state[payload.tabId] = {};
+ },
+ init: (state, { payload }) => {
+ state[payload.tabId] = {};
+ },
+ remove: (state, { payload }) => {
+ delete state[payload.tabId];
+ },
+ },
+});
+
+export const { fetchSuccess, remove, reset, init } = queryResultSlice.actions;
+
+export const selectQueryResult = (state) => state.queryResults;
+
+export default queryResultSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/slices/query_slice.ts b/dashboards-observability/public/components/explorer/slices/query_slice.ts
new file mode 100644
index 000000000..68677398d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/query_slice.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import {
+ RAW_QUERY,
+ FINAL_QUERY,
+ SELECTED_DATE_RANGE,
+ REDUX_EXPL_SLICE_QUERIES,
+ INDEX,
+ SELECTED_TIMESTAMP,
+ APP_ANALYTICS_TAB_ID_REGEX,
+} from '../../../../common/constants/explorer';
+
+const initialQueryState = {
+ [RAW_QUERY]: '',
+ [FINAL_QUERY]: '',
+ [INDEX]: '',
+ [SELECTED_TIMESTAMP]: '',
+ [SELECTED_DATE_RANGE]: ['now-15m', 'now'],
+};
+
+const appBaseQueryState = {
+ [RAW_QUERY]: '',
+ [FINAL_QUERY]: '',
+ [INDEX]: '',
+ [SELECTED_TIMESTAMP]: '',
+ [SELECTED_DATE_RANGE]: ['now-24h', 'now'],
+};
+
+const initialState = {
+ [initialTabId]: {
+ ...initialQueryState,
+ },
+};
+
+export const queriesSlice = createSlice({
+ name: REDUX_EXPL_SLICE_QUERIES,
+ initialState,
+ reducers: {
+ changeQuery: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...state[payload.tabId],
+ ...payload.query,
+ };
+ },
+ changeDateRange: (state, { payload }) => {
+ state[payload.tabId] = {
+ ...state[payload.tabId],
+ ...payload.data,
+ };
+ },
+ init: (state, { payload }) => {
+ state[payload.tabId] = payload.tabId.match(APP_ANALYTICS_TAB_ID_REGEX)
+ ? appBaseQueryState
+ : initialQueryState;
+ },
+ remove: (state, { payload }) => {
+ delete state[payload.tabId];
+ },
+ },
+ extraReducers: (builder) => {},
+});
+
+export const { changeQuery, changeDateRange, remove, init } = queriesSlice.actions;
+
+export const selectQueries = (state) => state.queries;
+
+export default queriesSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/slices/query_tab_slice.ts b/dashboards-observability/public/components/explorer/slices/query_tab_slice.ts
new file mode 100644
index 000000000..d509b21ff
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/query_tab_slice.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ createSlice
+} from '@reduxjs/toolkit';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import {
+ SELECTED_QUERY_TAB,
+ QUERY_TAB_IDS,
+ NEW_SELECTED_QUERY_TAB,
+ REDUX_EXPL_SLICE_QUERY_TABS
+} from '../../../../common/constants/explorer';
+import { assign } from 'lodash';
+
+const initialState = {
+ queryTabIds: [initialTabId],
+ selectedQueryTab: initialTabId,
+ tabNames: {}
+};
+
+export const queryTabsSlice = createSlice({
+ name: REDUX_EXPL_SLICE_QUERY_TABS,
+ initialState,
+ reducers: {
+ addTab: (state, { payload }) => {
+ state[QUERY_TAB_IDS].push(payload.tabId);
+ state[SELECTED_QUERY_TAB] = payload.tabId;
+ },
+ removeTab: (state, { payload }) => {
+ state[QUERY_TAB_IDS] = state[QUERY_TAB_IDS].filter((tabId) => {
+ return tabId !== payload.tabId;
+ });
+ if (payload[NEW_SELECTED_QUERY_TAB]) {
+ state[SELECTED_QUERY_TAB] = payload[NEW_SELECTED_QUERY_TAB];
+ }
+ },
+ updateTabName: (state, { payload }) => {
+ const newTabNames = {
+ [payload.tabId]: payload.tabName
+ };
+ assign(state.tabNames, newTabNames);
+ },
+ setSelectedQueryTab: (state, { payload }) => {
+ state[SELECTED_QUERY_TAB] = payload.tabId;
+ }
+ },
+ extraReducers: (builder) => {}
+});
+
+export const {
+ addTab,
+ removeTab,
+ setSelectedQueryTab,
+ updateTabName
+} = queryTabsSlice.actions;
+
+export const selectQueryTabs = (state) => state.explorerTabs;
+
+export default queryTabsSlice.reducer;
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/slices/visualization_slice.ts b/dashboards-observability/public/components/explorer/slices/visualization_slice.ts
new file mode 100644
index 000000000..55888a499
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/visualization_slice.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import { REDUX_EXPL_SLICE_VISUALIZATION } from '../../../../common/constants/explorer';
+
+const initialState = {
+ [initialTabId]: {},
+};
+
+export const explorerVisualizationSlice = createSlice({
+ name: REDUX_EXPL_SLICE_VISUALIZATION,
+ initialState,
+ reducers: {
+ render: (state, { payload }) => {
+ state[payload.tabId] = payload.data;
+ },
+ reset: (state, { payload }) => {
+ state[payload.tabId] = {};
+ },
+ },
+ extraReducers: (builder) => {},
+});
+
+export const { render, reset } = explorerVisualizationSlice.actions;
+
+export const selectExplorerVisualization = (state) => state.explorerVisualization;
+
+export default explorerVisualizationSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/slices/viualization_config_slice.ts b/dashboards-observability/public/components/explorer/slices/viualization_config_slice.ts
new file mode 100644
index 000000000..bfdd94af1
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/slices/viualization_config_slice.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { createSlice } from '@reduxjs/toolkit';
+import { initialTabId } from '../../../framework/redux/store/shared_state';
+import { REDUX_EXPL_SLICE_VISUALIZATION } from '../../../../common/constants/explorer';
+
+const initialState = {
+ [initialTabId]: {},
+};
+
+export const visualizationConfigSlice = createSlice({
+ name: 'explorerVizConfigs',
+ initialState,
+ reducers: {
+ change: (state, { payload }) => {
+ const { tabId, vizId, data } = payload;
+ let curVizPrevState = {};
+ if (state[tabId] && state[tabId][vizId]) {
+ curVizPrevState = { ...state[tabId][vizId] };
+ }
+ state[tabId] = {
+ ...state[tabId],
+ [vizId]: {
+ ...curVizPrevState,
+ ...data,
+ },
+ };
+ },
+ reset: (state, { payload }) => {
+ state[payload.tabId] = {};
+ },
+ init: (state, { payload }) => {
+ state[payload.tabId] = {};
+ },
+ },
+ extraReducers: (builder) => {},
+});
+
+export const { change, reset, init } = visualizationConfigSlice.actions;
+
+export const selectVisualizationConfig = (state) => state.explorerVisualizationConfig;
+
+export default visualizationConfigSlice.reducer;
diff --git a/dashboards-observability/public/components/explorer/timechart_header/__tests__/__snapshots__/timechart_header.test.tsx.snap b/dashboards-observability/public/components/explorer/timechart_header/__tests__/__snapshots__/timechart_header.test.tsx.snap
new file mode 100644
index 000000000..af8ade96a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/timechart_header/__tests__/__snapshots__/timechart_header.test.tsx.snap
@@ -0,0 +1,333 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Time chart header component Renders Time chart header component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Minute
+
+
+ Hour
+
+
+ Day
+
+
+ Week
+
+
+ Month
+
+
+ Year
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/timechart_header/__tests__/timechart_header.test.tsx b/dashboards-observability/public/components/explorer/timechart_header/__tests__/timechart_header.test.tsx
new file mode 100644
index 000000000..ba43d1a7d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/timechart_header/__tests__/timechart_header.test.tsx
@@ -0,0 +1,34 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { TimechartHeader } from '../timechart_header';
+import { TIME_INTERVAL_OPTIONS } from '../../../../../common/constants/explorer';
+
+describe.skip('Time chart header component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders Time chart header component', async () => {
+ const onChangeInterval = jest.fn();
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/timechart_header/index.ts b/dashboards-observability/public/components/explorer/timechart_header/index.ts
new file mode 100644
index 000000000..d9198de35
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/timechart_header/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { TimechartHeader } from './timechart_header';
diff --git a/dashboards-observability/public/components/explorer/timechart_header/timechart_header.tsx b/dashboards-observability/public/components/explorer/timechart_header/timechart_header.tsx
new file mode 100644
index 000000000..651563023
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/timechart_header/timechart_header.tsx
@@ -0,0 +1,79 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useEffect, useCallback } from 'react';
+import { EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiText, EuiSelect } from '@elastic/eui';
+import { I18nProvider } from '@osd/i18n/react';
+import { i18n } from '@osd/i18n';
+import moment from 'moment';
+
+export interface TimechartHeaderProps {
+ /**
+ * Format of date to be displayed
+ */
+ dateFormat?: string;
+ /**
+ * Range of dates to be displayed
+ */
+ timeRange?: {
+ from: string;
+ to: string;
+ };
+ /**
+ * Interval Options
+ */
+ options: Array<{ text: string; value: string }>;
+ /**
+ * changes the interval
+ */
+ onChangeInterval: (interval: string) => void;
+ /**
+ * selected interval
+ */
+ stateInterval: string;
+}
+
+export function TimechartHeader({
+ options,
+ onChangeInterval
+}: TimechartHeaderProps) {
+ const [interval, setInterval] = useState(options[0].value);
+
+ const handleIntervalChange = (e: React.ChangeEvent) => {
+ setInterval(e.target.value);
+ onChangeInterval(e.target.value.length > 2 ? e.target.value.slice(5) : e.target.value);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/utils/index.tsx b/dashboards-observability/public/components/explorer/utils/index.tsx
new file mode 100644
index 000000000..f509de965
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/utils/index.tsx
@@ -0,0 +1,15 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export {
+ getTrs,
+ getHeaders,
+ fetchSurroundingData,
+ rangeNumDocs,
+ populateDataGrid,
+ isValidTraceId,
+ formatError,
+ findAutoInterval,
+} from './utils';
diff --git a/dashboards-observability/public/components/explorer/utils/utils.tsx b/dashboards-observability/public/components/explorer/utils/utils.tsx
new file mode 100644
index 000000000..fc29e7a2f
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/utils/utils.tsx
@@ -0,0 +1,287 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { uniqueId } from 'lodash';
+import React from 'react';
+import moment from 'moment';
+import dateMath from '@elastic/datemath';
+import { IExplorerFields, IField } from '../../../../common/types/explorer';
+import { DocViewRow, IDocType } from '../docTable';
+import { HttpStart } from '../../../../../../src/core/public';
+import PPLService from '../../../services/requests/ppl';
+import { TIME_INTERVAL_OPTIONS } from '../../../../common/constants/explorer';
+import { PPL_DATE_FORMAT, PPL_INDEX_REGEX } from '../../../../common/constants/shared';
+
+// Create Individual table rows for events datagrid and flyouts
+export const getTrs = (
+ http: HttpStart,
+ explorerFields: IField[],
+ limit: number,
+ setLimit: React.Dispatch>,
+ PAGE_SIZE: number,
+ timeStampField: any,
+ explorerFieldsFull: IExplorerFields,
+ pplService: PPLService,
+ rawQuery: string,
+ rowRefs: Array<
+ React.RefObject<{
+ closeAllFlyouts(openDocId: string): void;
+ }>
+ >,
+ setRowRefs: React.Dispatch<
+ React.SetStateAction<
+ Array<
+ React.RefObject<{
+ closeAllFlyouts(openDocId: string): void;
+ }>
+ >
+ >
+ >,
+ onFlyoutOpen: (docId: string) => void,
+ docs: any[] = [],
+ prevTrs: any[] = []
+) => {
+ if (prevTrs.length >= docs.length) return prevTrs;
+
+ // reset limit if no previous table rows
+ if (prevTrs.length === 0 && limit !== PAGE_SIZE) setLimit(PAGE_SIZE);
+ const trs = prevTrs.slice();
+
+ const upperLimit = Math.min(trs.length === 0 ? PAGE_SIZE : limit, docs.length);
+ const tempRefs = rowRefs;
+ for (let i = trs.length; i < upperLimit; i++) {
+ const docId = uniqueId('doc_view');
+ const tempRowRef = React.createRef<{
+ closeAllFlyouts(openDocId: string): void;
+ }>();
+ tempRefs.push(tempRowRef);
+ trs.push(
+
+ );
+ }
+ setRowRefs(tempRefs);
+ return trs;
+};
+
+// Create table headers for events datagrid and flyouts
+export const getHeaders = (fields: any, defaultCols: string[], isFlyout?: boolean) => {
+ let tableHeadContent = null;
+ if (!fields || fields.length === 0) {
+ tableHeadContent = (
+ <>
+ {defaultCols.map((colName: string) => {
+ return {colName} ;
+ })}
+ >
+ );
+ } else {
+ tableHeadContent = fields.map((selField: any) => {
+ return {selField.name} ;
+ });
+
+ if (!isFlyout) {
+ tableHeadContent.unshift( );
+ }
+ }
+
+ return {tableHeadContent} ;
+};
+
+// Populate Events datagrid and flyouts
+export const populateDataGrid = (
+ explorerFields: IExplorerFields,
+ header1: JSX.Element,
+ body1: JSX.Element,
+ header2: JSX.Element,
+ body2: JSX.Element
+) => {
+ return (
+ <>
+
+ {explorerFields?.queriedFields && explorerFields.queriedFields.length > 0 && (
+
+ )}
+ {explorerFields?.queriedFields &&
+ explorerFields?.queriedFields?.length > 0 &&
+ explorerFields.selectedFields?.length === 0 ? null : (
+
+ )}
+
+ >
+ );
+};
+
+/* Builds Final Query for the surrounding events
+ * -> Final Query is as follows:
+ * -> finalQuery = indexPartOfQuery + timeQueryFilter + filterPartOfQuery + sortFilter
+ *
+ * Example Query for 5 new events:
+ * -> rawQuery: source = opensearch_dashboards_sample_data_logs | where geo.src = 'US'
+ * -> indexPartOfQuery = 'source = opensearch_dashboards_sample_data_logs'
+ * -> filterPartOfQuery = '| where geo.src = 'US''
+ * -> timeQueryFilter = ' | where tiimestamp > 2022-01-16 03:26:21.326'
+ * -> sortFilter = '| sort + tiimestamp | head 5'
+ * -> finalQuery = 'source logs_test | where tiimestamp > 2022-01-16 03:26:21.326 | where geo.src = 'US' | sort + timeStampField | head 5'
+ */
+const composeFinalQuery = (
+ rawQuery: string,
+ timeStampField: string,
+ eventTime: string,
+ numDocs: number,
+ typeOfDocs: 'new' | 'old'
+) => {
+ const indexMatchArray = rawQuery.match(PPL_INDEX_REGEX);
+ if (indexMatchArray == null) {
+ throw Error('index not found in Query');
+ }
+ const indexPartOfQuery = indexMatchArray[0];
+ const filterPartOfQuery = rawQuery.replace(PPL_INDEX_REGEX, '');
+ const timeSymbol = typeOfDocs === 'new' ? '>' : '<';
+ const sortSymbol = typeOfDocs === 'new' ? '+' : '-';
+ const timeQueryFilter = ` | where ${timeStampField} ${timeSymbol} '${eventTime}'`;
+ const sortFilter = ` | sort ${sortSymbol} ${timeStampField} | head ${numDocs}`;
+
+ return indexPartOfQuery + timeQueryFilter + filterPartOfQuery + sortFilter;
+};
+
+const createTds = (
+ docs: IDocType[],
+ selectedCols: IField[],
+ getTds: (doc: IDocType, selectedCols: IField[], isFlyout: boolean) => JSX.Element[]
+) => {
+ return docs.map((doc: IDocType) => (
+ {getTds(doc, selectedCols, true).slice(1)}
+ ));
+};
+
+// fetches Surrounding events based on a timestamp
+export const fetchSurroundingData = async (
+ pplService: PPLService,
+ rawQuery: string,
+ timeStampField: string,
+ eventTime: string,
+ numDocs: number,
+ typeOfDocs: 'new' | 'old',
+ setEventsData: React.Dispatch>,
+ setIsError: React.Dispatch>,
+ setLoadingData: React.Dispatch>,
+ selectedCols: IField[],
+ getTds: (doc: IDocType, selectedCols: IField[], isFlyout: boolean) => JSX.Element[]
+) => {
+ let resultCount = 0;
+ let isErred = false;
+ const pplEventTime = moment.utc(eventTime).format(PPL_DATE_FORMAT);
+ setLoadingData(true);
+ setIsError('');
+
+ let finalQuery = '';
+ try {
+ finalQuery = composeFinalQuery(rawQuery, timeStampField, pplEventTime, numDocs, typeOfDocs);
+ } catch (error) {
+ const errorMessage = 'Issue in building surrounding data query';
+ setIsError(errorMessage);
+ isErred = true;
+ console.error(errorMessage, error);
+ setLoadingData(false);
+ return resultCount;
+ }
+
+ await pplService
+ .fetch({ query: finalQuery, format: 'jdbc' })
+ .then((res) => {
+ const resuleData = typeOfDocs == 'new' ? res.jsonData.reverse() : res.jsonData;
+ resultCount = resuleData.length;
+ setEventsData(createTds(resuleData, selectedCols, getTds));
+ })
+ .catch((error: Error) => {
+ setIsError(error.message);
+ isErred = true;
+ console.error(error);
+ })
+ .finally(() => {
+ setLoadingData(false);
+ });
+
+ if (resultCount !== numDocs && !isErred) {
+ const errorMessage =
+ resultCount !== 0
+ ? `Could only find ${resultCount} ${typeOfDocs} event${resultCount === 1 ? '' : 's'}!`
+ : `Could not find any ${typeOfDocs} event!`;
+ setIsError(errorMessage);
+ }
+
+ return resultCount;
+};
+
+// contains 0 <= value <= 10000
+export const rangeNumDocs = (value: number) => {
+ return value > 10000 ? 10000 : value < 0 ? 0 : value;
+};
+
+// check traceId Byte Size
+export const isValidTraceId = (traceId: string) => {
+ return new Blob([traceId]).size === 32;
+};
+
+export const formatError = (name: string, message: string, details: string) => {
+ return {
+ name,
+ message,
+ body: {
+ attributes: {
+ error: {
+ caused_by: {
+ type: '',
+ reason: details,
+ },
+ },
+ },
+ },
+ };
+};
+
+export const findAutoInterval = (start: string = '', end: string = '') => {
+ let minInterval = 'y';
+ if (start?.length === 0 || end?.length === 0 || start === end)
+ return ['d', [...TIME_INTERVAL_OPTIONS]];
+ const momentStart = dateMath.parse(start)!;
+ const momentEnd = dateMath.parse(end)!;
+ const diffSeconds = momentEnd.unix() - momentStart.unix();
+
+ // less than 1 second
+ if (diffSeconds <= 1) minInterval = 'ms';
+ // less than 2 minutes
+ else if (diffSeconds <= 60 * 2) minInterval = 's';
+ // less than 2 hours
+ else if (diffSeconds <= 3600 * 2) minInterval = 'm';
+ // less than 2 days
+ else if (diffSeconds <= 86400 * 2) minInterval = 'h';
+ // less than 1 month
+ else if (diffSeconds <= 86400 * 31) minInterval = 'd';
+ // less than 3 months
+ else if (diffSeconds <= 86400 * 93) minInterval = 'w';
+ // less than 1 year
+ else if (diffSeconds <= 86400 * 366) minInterval = 'M';
+
+ return [minInterval, [{ text: 'Auto', value: 'auto_' + minInterval }, ...TIME_INTERVAL_OPTIONS]];
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/datapanel.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/datapanel.test.tsx.snap
new file mode 100644
index 000000000..3aa9e30e6
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/datapanel.test.tsx.snap
@@ -0,0 +1,6258 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Data panel component Renders data panel component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Available fields
+
+
+ }
+ extraAction={
+
+ 20
+
+ }
+ id="1"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ paddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Available fields
+
+
+
+
+
+
+
+
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clientip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ event
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ extension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ geo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ host
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ machine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ memory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ message
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ phpmemory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ referer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ response
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ timestamp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ utc_time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_accordion.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_accordion.test.tsx.snap
new file mode 100644
index 000000000..3b69e89a7
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_accordion.test.tsx.snap
@@ -0,0 +1,5890 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization fields accordion component Renders fields accordion component 1`] = `
+
+
+
+ Available fields
+
+
+ }
+ extraAction={
+
+ 20
+
+ }
+ id="3367"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ paddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Available fields
+
+
+
+
+
+
+
+
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ bytes
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ bytes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ clientip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ clientip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ event
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ event
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ extension
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ extension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ geo
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ geo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ host
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ host
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ index
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ index
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ ip
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ip
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ machine
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ machine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ memory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ memory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ message
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ message
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ phpmemory
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ phpmemory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ referer
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ referer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ request
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ request
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ response
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ response
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ tags
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ timestamp
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ timestamp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ url
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ url
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ utc_time
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ utc_time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_item.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_item.test.tsx.snap
new file mode 100644
index 000000000..f896951af
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_item.test.tsx.snap
@@ -0,0 +1,288 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization field item component Renders field item component 1`] = `
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ />
+
+ }
+ className="lnsFieldItem__popoverAnchor"
+ closePopover={[Function]}
+ data-test-subj="lnsFieldListPanelField"
+ display="block"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={true}
+ panelClassName="lnsFieldItem__fieldPanel"
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+ }
+ fieldInfoIcon={
+
+ }
+ fieldName={
+
+ agent
+
+ }
+ isActive={false}
+ onClick={[Function]}
+ onDragEnd={[Function]}
+ onDragLeave={[Function]}
+ onDragOver={[Function]}
+ onDragStart={[Function]}
+ onDrop={[Function]}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ agent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_list.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_list.test.tsx.snap
new file mode 100644
index 000000000..5ffdbb49d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/field_list.test.tsx.snap
@@ -0,0 +1,234 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization field list component Renders field list component 1`] = `
+
+
+
+
+
+
+ Available fields
+
+
+ }
+ extraAction={
+
+ 0
+
+ }
+ id="3327"
+ initialIsOpen={false}
+ isLoading={false}
+ isLoadingMessage={false}
+ paddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Available fields
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/lens_field_icon.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/lens_field_icon.test.tsx.snap
new file mode 100644
index 000000000..d9cbea0a6
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/__snapshots__/lens_field_icon.test.tsx.snap
@@ -0,0 +1,55 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Visualization field icon component Renders field icon component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/datapanel.test.tsx b/dashboards-observability/public/components/explorer/visualizations/__tests__/datapanel.test.tsx
new file mode 100644
index 000000000..d6f99c338
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/datapanel.test.tsx
@@ -0,0 +1,45 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { DataPanel } from '../datapanel';
+import {
+ SELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ UNSELECTED_FIELDS,
+ QUERIED_FIELDS
+} from '../../../../../common/constants/explorer';
+import {
+ AVAILABLE_FIELDS as SIDEBAR_AVAILABLE_FIELDS,
+ QUERY_FIELDS
+} from '../../../../../test/event_analytics_constants';
+
+describe('Data panel component', () => {
+ configure({ adapter: new Adapter() });
+
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS,
+ [QUERIED_FIELDS]: QUERY_FIELDS
+ };
+ it('Renders data panel component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/field_accordion.test.tsx b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_accordion.test.tsx
new file mode 100644
index 000000000..d171927b3
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_accordion.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { FieldsAccordion } from '../fields_accordion';
+import {
+ AVAILABLE_FIELDS
+} from '../../../../../test/event_analytics_constants';
+
+describe('Visualization fields accordion component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders fields accordion component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/field_item.test.tsx b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_item.test.tsx
new file mode 100644
index 000000000..c5e4cd8f8
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_item.test.tsx
@@ -0,0 +1,36 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { FieldItem } from '../field_item';
+import {
+ AVAILABLE_FIELDS
+} from '../../../../../test/event_analytics_constants';
+
+describe('Visualization field item component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders field item component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/field_list.test.tsx b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_list.test.tsx
new file mode 100644
index 000000000..15f97b5c2
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/field_list.test.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { FieldList } from '../fieldList';
+import {
+ AVAILABLE_FIELDS
+} from '../../../../../test/event_analytics_constants';
+
+describe('Visualization field list component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders field list component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/__tests__/lens_field_icon.test.tsx b/dashboards-observability/public/components/explorer/visualizations/__tests__/lens_field_icon.test.tsx
new file mode 100644
index 000000000..bdc846feb
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/__tests__/lens_field_icon.test.tsx
@@ -0,0 +1,29 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { LensFieldIcon } from '../lens_field_icon';
+
+describe('Visualization field icon component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders field icon component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/_mixins.scss b/dashboards-observability/public/components/explorer/visualizations/_mixins.scss
new file mode 100644
index 000000000..ae22f3905
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/_mixins.scss
@@ -0,0 +1,54 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// sass-lint:disable-block indentation, no-color-keywords
+
+// SASSTODO: Create this in EUI
+@mixin lnsOverflowShadowHorizontal {
+ $hideHeight: $euiScrollBarCorner * 1.25;
+ mask-image: linear-gradient(
+ to right,
+ transparentize(red, .9) 0%,
+ transparentize(red, 0) $hideHeight,
+ transparentize(red, 0) calc(100% - #{$hideHeight}),
+ transparentize(red, .9) 100%
+ );
+}
+
+// Static styles for a draggable item
+@mixin lnsDraggable {
+ @include euiSlightShadow;
+ background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade);
+ border: $euiBorderWidthThin dashed transparent;
+ cursor: grab;
+}
+
+// Static styles for a drop area
+@mixin lnsDroppable {
+ border: $euiBorderWidthThin dashed $euiBorderColor;
+}
+
+// Hovering state for drag item and drop area
+@mixin lnsDragDropHover {
+ &:hover {
+ border: $euiBorderWidthThin dashed $euiColorMediumShade;
+ }
+}
+
+// Style for drop area when there's an item being dragged
+@mixin lnsDroppableActive {
+ background-color: transparentize($euiColorVis0, .9);
+}
+
+// Style for drop area while hovering with item
+@mixin lnsDroppableActiveHover {
+ background-color: transparentize($euiColorVis0, .75);
+ border: $euiBorderWidthThin dashed $euiColorVis0;
+}
+
+// Style for drop area that is not allowed for current item
+@mixin lnsDroppableNotAllowed {
+ opacity: .5;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/_variables.scss b/dashboards-observability/public/components/explorer/visualizations/_variables.scss
new file mode 100644
index 000000000..a4248f814
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/_variables.scss
@@ -0,0 +1,10 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+$lnsPanelMinWidth: $euiSize * 18;
+
+// These sizes also match canvas' page thumbnails for consistency
+$lnsSuggestionHeight: 100px;
+$lnsSuggestionWidth: 150px;
diff --git a/dashboards-observability/public/components/explorer/visualizations/app.scss b/dashboards-observability/public/components/explorer/visualizations/app.scss
new file mode 100644
index 000000000..2f01e1b8e
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/app.scss
@@ -0,0 +1,47 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsAppWrapper {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+}
+
+.lnsApp {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: hidden;
+}
+
+.lnsApp__header {
+ border-bottom: $euiBorderThin;
+}
+
+.lnsApp__frame {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+}
+
+.lensChartIcon__subdued {
+ fill: $euiTextSubduedColor;
+
+ // Not great, but the easiest way to fix the gray fill when stuck in a button with a fill
+ // Like when selected in a button group
+ .euiButton--fill & {
+ fill: currentColor;
+ }
+}
+
+.lensChartIcon__accent {
+ fill: $euiColorVis0;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/DefaultEditorControls.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/DefaultEditorControls.tsx
new file mode 100644
index 000000000..2e653cd1d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/DefaultEditorControls.tsx
@@ -0,0 +1,58 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiButton,
+ EuiButtonEmpty,
+ EuiButtonToggle,
+ EuiToolTip,
+} from '@elastic/eui';
+
+export const DefaultEditorControls = ({
+ isInvalid,
+ isDirty,
+ onConfigUpdate,
+ onConfigDiscard,
+}: any) => {
+ return (
+
+
+
+
+ Reset
+
+
+
+ {isInvalid ? (
+
+
+ Preview
+
+
+ ) : (
+
+ Preview
+
+ )}
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap
new file mode 100644
index 000000000..319bdb828
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap
@@ -0,0 +1,3666 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Config panel component Renders config panel wrapper component with fields 1`] = `
+
+
+ ,
+ "id": "setting-panel",
+ "name": "Settings",
+ },
+ ]
+ }
+ >
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Y-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Config panel component Renders empty config panel wrapper component 1`] = `
+
+
+ ,
+ "id": "setting-panel",
+ "name": "Settings",
+ },
+ ]
+ }
+ >
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Y-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Config panel component Renders panel item component 1`] = `
+
+
+ ,
+ "id": "setting-panel",
+ "name": "Settings",
+ },
+ ]
+ }
+ >
+
+
+
+
+
+
+ Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Y-axis
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select a field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Advanced
+
+
+
+
+
+
+
+
+
+ here goes advanced setting
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/config_panel.test.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/config_panel.test.tsx
new file mode 100644
index 000000000..24f76212a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/__tests__/config_panel.test.tsx
@@ -0,0 +1,68 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+// import { ConfigPanel } from '../config_panel';
+import {
+ SELECTED_FIELDS,
+ AVAILABLE_FIELDS,
+ UNSELECTED_FIELDS,
+ QUERIED_FIELDS,
+} from '../../../../../../common/constants/explorer';
+import {
+ AVAILABLE_FIELDS as SIDEBAR_AVAILABLE_FIELDS,
+ QUERY_FIELDS,
+} from '../../../../../../test/event_analytics_constants';
+
+describe.skip('Config panel component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders empty config panel wrapper component', async () => {
+ const wrapper = mount( );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('Renders config panel wrapper component with fields', async () => {
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS,
+ [QUERIED_FIELDS]: QUERY_FIELDS,
+ };
+
+ const wrapper = mount( );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('Renders panel item component', async () => {
+ const explorerFields = {
+ [SELECTED_FIELDS]: [],
+ [UNSELECTED_FIELDS]: [],
+ [AVAILABLE_FIELDS]: SIDEBAR_AVAILABLE_FIELDS,
+ [QUERIED_FIELDS]: QUERY_FIELDS,
+ };
+
+ const wrapper = mount( );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/configPanelItem.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/configPanelItem.tsx
new file mode 100644
index 000000000..681096a63
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/configPanelItem.tsx
@@ -0,0 +1,42 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { uniqueId, isEmpty } from 'lodash';
+import { EuiTitle, EuiComboBox, EuiSpacer } from '@elastic/eui';
+
+export const PanelItem = ({
+ paddingTitle,
+ selectedAxis,
+ dropdownList,
+ onSelectChange,
+ isSingleSelection = false,
+}: any) => {
+ const options = dropdownList.map((item) => {
+ return {
+ ...item,
+ label: item.name,
+ };
+ });
+
+ return (
+ <>
+
+ {paddingTitle}
+
+
+
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_availability.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_availability.tsx
new file mode 100644
index 000000000..21978fce9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_availability.tsx
@@ -0,0 +1,194 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useCallback, useState } from 'react';
+import {
+ EuiButton,
+ EuiAccordion,
+ EuiFormRow,
+ EuiFieldNumber,
+ EuiColorPicker,
+ EuiSpacer,
+ EuiIcon,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFieldText,
+ EuiSelect,
+ htmlIdGenerator,
+ EuiText,
+} from '@elastic/eui';
+import { isEmpty } from 'lodash';
+import { PPL_SPAN_REGEX } from '../../../../../../../common/constants/shared';
+import { AvailabilityInfoFlyout } from '../../../../../application_analytics/components/flyout_components/availability_info_flyout';
+
+export interface AvailabilityUnitType {
+ thid: string;
+ name: string;
+ color: string;
+ value: number;
+ expression: string;
+}
+
+export const ConfigAvailability = ({ visualizations, onConfigChange, vizState = {} }: any) => {
+ const [flyoutOpen, setFlyoutOpen] = useState(false);
+ const closeFlyout = () => setFlyoutOpen(false);
+ const addButtonText = '+ Add availability level';
+ const getAvailabilityUnit = () => {
+ return {
+ thid: htmlIdGenerator('avl')(),
+ name: '',
+ color: '#FC0505',
+ value: 0,
+ expression: '≥',
+ };
+ };
+
+ const expressionOptions = [
+ { value: '≥', text: '≥' },
+ { value: '≤', text: '≤' },
+ { value: '>', text: '>' },
+ { value: '<', text: '<' },
+ { value: '=', text: '=' },
+ { value: '≠', text: '≠' },
+ ];
+
+ const availabilityAccordionButton = (
+
+ Availability
+ setFlyoutOpen(true)} size="m" />
+
+ );
+
+ const hasSpanInApp =
+ visualizations.data.query.finalQuery.search(PPL_SPAN_REGEX) > 0 &&
+ visualizations.data.appData.fromApp &&
+ ['bar', 'line'].includes(visualizations.vis.id);
+
+ const handleConfigChange = useCallback(
+ (changes: any) => {
+ onConfigChange({
+ ...vizState,
+ level: changes,
+ });
+ },
+ [onConfigChange, vizState]
+ );
+
+ const handleAddAvailability = useCallback(() => {
+ let res = vizState.level;
+ if (isEmpty(vizState.level)) res = [];
+ handleConfigChange([getAvailabilityUnit(), ...res]);
+ }, [vizState, handleConfigChange]);
+
+ const handleAvailabilityChange = useCallback(
+ (thrId, thrName) => {
+ return (event: any) => {
+ handleConfigChange([
+ ...vizState.level.map((th: AvailabilityUnitType) => {
+ if (thrId !== th.thid) return th;
+ return {
+ ...th,
+ [thrName]: (thrName === 'color' ? event : event?.target?.value) || '',
+ };
+ }),
+ ]);
+ };
+ },
+ [vizState, handleConfigChange]
+ );
+
+ const handleAvailabilityDelete = useCallback(
+ (thrId) => {
+ return (event: any) => {
+ handleConfigChange([
+ ...vizState.level.filter((th: AvailabilityUnitType) => th.thid !== thrId),
+ ]);
+ };
+ },
+ [vizState, handleConfigChange]
+ );
+
+ return (
+ <>
+
+
+
+ {addButtonText}
+
+
+ {!isEmpty(vizState.level) &&
+ vizState.level.map((thr: AvailabilityUnitType) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+ })}
+
+ {flyoutOpen && }
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_chart_options.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_chart_options.tsx
new file mode 100644
index 000000000..db74dc66f
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_chart_options.tsx
@@ -0,0 +1,61 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useMemo, useCallback } from 'react';
+import { EuiAccordion, EuiSpacer } from '@elastic/eui';
+import { PanelItem } from '../../configPanelItem';
+
+export const ConfigChartOptions = ({
+ visualizations,
+ schemas,
+ vizState,
+ handleConfigChange,
+}: any) => {
+ const { data } = visualizations;
+ const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData;
+ const handleConfigurationChange = useCallback(
+ (stateFiledName) => {
+ return (changes) => {
+ handleConfigChange({
+ ...vizState,
+ [stateFiledName]: changes,
+ });
+ };
+ },
+ [handleConfigChange, vizState]
+ );
+
+ const dimensions = useMemo(() => {
+ return schemas.map((schema, index) => {
+ const DimensionComponent = schema.component || PanelItem;
+ const params = {
+ paddingTitle: schema.name,
+ advancedTitle: 'advancedTitle',
+ dropdownList: schema?.options?.map((option) => ({ name: option })) || fields,
+ onSelectChange: handleConfigurationChange(schema.mapTo),
+ isSingleSelection: schema.isSingleSelection,
+ selectedAxis: vizState[schema.mapTo],
+ ...schema.props,
+ };
+ return (
+ <>
+
+
+ >
+ );
+ });
+ }, [schemas, fields, vizState, handleConfigurationChange]);
+
+ return (
+
+ {dimensions}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_data_links.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_data_links.tsx
new file mode 100644
index 000000000..e183de7b8
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_data_links.tsx
@@ -0,0 +1,15 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiAccordion, EuiButton } from '@elastic/eui';
+
+export const ConfigDataLinks = (props: any) => {
+ return (
+
+ + Add link
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_gauge_options.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_gauge_options.tsx
new file mode 100644
index 000000000..6bfca43dd
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_gauge_options.tsx
@@ -0,0 +1,83 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useMemo, useCallback } from 'react';
+import { indexOf, toString } from 'lodash';
+import { EuiAccordion, EuiSpacer } from '@elastic/eui';
+import { PanelItem } from '../../configPanelItem';
+import { NUMERICAL_FIELDS } from '../../../../../../../common/constants/shared';
+
+export const ConfigGaugeValueOptions = ({
+ visualizations,
+ schemas,
+ vizState,
+ handleConfigChange,
+ sectionName,
+}: any) => {
+ const { data } = visualizations;
+ const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData;
+ const handleConfigurationChange = useCallback(
+ (stateFiledName) => {
+ return (changes) => {
+ handleConfigChange({
+ ...vizState,
+ [stateFiledName]: changes,
+ });
+ };
+ },
+ [handleConfigChange, vizState]
+ );
+
+ const dropdownLists = {
+ series: fields,
+ value: [],
+ };
+
+ if (vizState?.series && vizState?.series[0]?.type) {
+ if (indexOf(NUMERICAL_FIELDS, vizState?.series[0]?.type) > 0) {
+ dropdownLists.value = [...fields];
+ } else {
+ dropdownLists.value = [
+ ...vizData[vizState?.series[0]?.name].map((val) => ({
+ name: val,
+ type: vizState?.series[0]?.type,
+ })),
+ ];
+ }
+ }
+
+ const dimensions = useMemo(() => {
+ return schemas.map((schema, index) => {
+ const DimensionComponent = schema.component || PanelItem;
+ const params = {
+ paddingTitle: schema.name,
+ advancedTitle: 'advancedTitle',
+ dropdownList: dropdownLists[schema.mapTo].map((item) => ({ ...item })),
+ onSelectChange: handleConfigurationChange(schema.mapTo),
+ isSingleSelection: schema.isSingleSelection,
+ selectedAxis: vizState[schema.mapTo],
+ vizState,
+ ...schema.props,
+ };
+ return (
+ <>
+
+
+ >
+ );
+ });
+ }, [schemas, vizState, handleConfigurationChange, dropdownLists]);
+
+ return (
+
+ {dimensions}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_panel_options.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_panel_options.tsx
new file mode 100644
index 000000000..a1a6d75d9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_panel_options.tsx
@@ -0,0 +1,53 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useCallback } from 'react';
+import { EuiFieldText, EuiForm, EuiFormRow, EuiTextArea, EuiAccordion } from '@elastic/eui';
+
+const helpText = 'Name your visualization.';
+
+export const ConfigPanelOptions = ({ visualizations, handleConfigChange, vizState }: any) => {
+ const { dataConfig = {} } = visualizations?.data?.userConfigs;
+
+ const handleConfigurationChange = useCallback(
+ (stateFiledName) => {
+ return (changes) => {
+ handleConfigChange({
+ ...vizState,
+ [stateFiledName]: changes,
+ });
+ };
+ },
+ [handleConfigChange, vizState]
+ );
+
+ return (
+
+
+
+ handleConfigurationChange('title')(e.target.value)}
+ value={vizState?.title || ''}
+ placeholder={'Title'}
+ />
+
+
+ handleConfigurationChange('description')(e.target.value)}
+ />
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_text.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_text.tsx
new file mode 100644
index 000000000..0fbdaaadd
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_text.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useCallback } from 'react';
+import { EuiMarkdownEditor, EuiAccordion } from '@elastic/eui';
+
+export const ConfigText = ({ visualizations, schemas, vizState, handleConfigChange }) => {
+ const handleTextChange = useCallback(
+ (stateFiledName) => {
+ return (changes) => {
+ handleConfigChange({
+ ...vizState,
+ [stateFiledName]: changes,
+ });
+ };
+ },
+ [handleConfigChange, vizState]
+ );
+
+ return (
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_thresholds.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_thresholds.tsx
new file mode 100644
index 000000000..c38e8e812
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_thresholds.tsx
@@ -0,0 +1,143 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useCallback } from 'react';
+import {
+ EuiButton,
+ EuiAccordion,
+ EuiFormRow,
+ EuiFieldNumber,
+ EuiColorPicker,
+ EuiSpacer,
+ EuiIcon,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFieldText,
+ htmlIdGenerator,
+} from '@elastic/eui';
+import { isEmpty } from 'lodash';
+
+export interface ThresholdUnitType {
+ thid: string;
+ name: string;
+ color: string;
+ value: number;
+}
+
+export const ConfigThresholds = ({
+ visualizations,
+ schemas,
+ vizState = [],
+ handleConfigChange,
+ sectionName = 'Thresholds',
+}: any) => {
+ const addButtonText = '+ Add threadshold';
+ const getThresholdUnit = () => {
+ return {
+ thid: htmlIdGenerator('thr')(),
+ name: '',
+ color: '#FC0505',
+ value: 0,
+ };
+ };
+
+ const handleAddThreshold = useCallback(() => {
+ let res = vizState;
+ if (isEmpty(vizState)) res = [];
+ handleConfigChange([getThresholdUnit(), ...res]);
+ }, [vizState, handleConfigChange]);
+
+ const handleThresholdChange = useCallback(
+ (thrId, thrName) => {
+ return (event: any) => {
+ handleConfigChange([
+ ...vizState.map((th: ThresholdUnitType) => {
+ if (thrId !== th.thid) return th;
+ return {
+ ...th,
+ [thrName]: (thrName === 'color' ? event : event?.target?.value) || '',
+ };
+ }),
+ ]);
+ };
+ },
+ [vizState, handleConfigChange]
+ );
+
+ const handleThresholdDelete = useCallback(
+ (thrId) => {
+ return () => {
+ handleConfigChange([...vizState.filter((th: ThresholdUnitType) => th.thid !== thrId)]);
+ };
+ },
+ [vizState, handleConfigChange]
+ );
+
+ return (
+
+
+ {addButtonText}
+
+
+ {!isEmpty(vizState) &&
+ vizState.map((thr: ThresholdUnitType) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+ })}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_value_options.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_value_options.tsx
new file mode 100644
index 000000000..f3b80e568
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_value_options.tsx
@@ -0,0 +1,65 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useMemo, useCallback } from 'react';
+import { EuiAccordion, EuiSpacer } from '@elastic/eui';
+import { PanelItem } from '../../configPanelItem';
+
+export const ConfigValueOptions = ({
+ visualizations,
+ schemas,
+ vizState,
+ handleConfigChange,
+ sectionName,
+}: any) => {
+ const { data } = visualizations;
+ const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData;
+ const handleConfigurationChange = useCallback(
+ (stateFiledName) => {
+ return (changes) => {
+ handleConfigChange({
+ ...vizState,
+ [stateFiledName]: changes,
+ });
+ };
+ },
+ [handleConfigChange, vizState]
+ );
+
+ const dimensions = useMemo(() => {
+ return schemas.map((schema, index) => {
+ const DimensionComponent = schema.component || PanelItem;
+ const params = {
+ paddingTitle: schema.name,
+ advancedTitle: 'advancedTitle',
+ dropdownList:
+ schema?.options?.map((option) => ({ name: option })) ||
+ fields.map((item) => ({ ...item })),
+ onSelectChange: handleConfigurationChange(schema.mapTo),
+ isSingleSelection: schema.isSingleSelection,
+ selectedAxis: vizState[schema.mapTo],
+ vizState,
+ ...schema.props,
+ };
+ return (
+ <>
+
+
+ >
+ );
+ });
+ }, [schemas, fields, vizState, handleConfigurationChange]);
+
+ return (
+
+ {dimensions}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_visualization_selector.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_visualization_selector.tsx
new file mode 100644
index 000000000..d56c3ec52
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/config_visualization_selector.tsx
@@ -0,0 +1,20 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiAccordion } from '@elastic/eui';
+
+export const ConfigVisualizationSelector = ({ children }: any) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/index.ts b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/index.ts
new file mode 100644
index 000000000..f75c9126b
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_controls/index.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { ConfigPanelOptions } from './config_panel_options';
+export { ConfigValueOptions } from './config_value_options';
+export { ConfigChartOptions } from './config_chart_options';
+export { ConfigDataLinks } from './config_data_links';
+export { ConfigThresholds } from './config_thresholds';
+export { ConfigText } from './config_text';
+export { ConfigGaugeValueOptions } from './config_gauge_options';
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_editor.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_editor.tsx
new file mode 100644
index 000000000..9b1590853
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/config_editor.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { PlotlyVizEditor } from '../../shared_components/plotly_viz_editor';
+
+export const ConfigEditor = ({
+ spec,
+ onConfigEditorChange,
+ setToast,
+ visualizations,
+ ...rest
+}: any) => {
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/default_vis_editor.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/default_vis_editor.tsx
new file mode 100644
index 000000000..0cbad5326
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_editor/default_vis_editor.tsx
@@ -0,0 +1,49 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiForm, EuiFormRow } from '@elastic/eui';
+import { ConfigPanelOptions } from './config_controls';
+
+export const VizDataPanel = ({ visualizations, onConfigChange, vizState = {}, tabProps }: any) => {
+ const handleConfigEditing = (stateFieldName) => {
+ return (changes) => {
+ onConfigChange({
+ ...vizState,
+ [stateFieldName]: changes,
+ });
+ };
+ };
+
+ const dynamicContent = tabProps.sections.map((section) => {
+ const Editor = section.editor;
+ return (
+
+
+
+ );
+ });
+
+ return (
+
+
+
+
+
+ {dynamicContent}
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.scss b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.scss
new file mode 100644
index 000000000..2a129f430
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.scss
@@ -0,0 +1,125 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsConfigPanel__addLayerBtn {
+ color: transparentize($euiColorMediumShade, .3);
+ // Remove EuiButton's default shadow to make button more subtle
+ // sass-lint:disable-block no-important
+ box-shadow: none !important;
+ border-color: $euiColorLightShade;
+}
+
+//
+// LAYOUT
+//
+
+$vis-editor-sidebar-min-width: 350px;
+
+.visEditorSidebar {
+ min-width: $vis-editor-sidebar-min-width;
+
+ // a hack for IE, issue: https://github.com/elastic/kibana/issues/66586
+ > .visEditorSidebar__formWrapper {
+ flex-basis: auto;
+ }
+}
+
+.visEditorSidebar__form {
+ @include flex-parent(1, 1, auto);
+ max-width: 100%;
+}
+
+.visEditorSidebar__config {
+ padding: $euiSizeS;
+}
+
+.visEditorSidebar__config-isHidden {
+ display: none;
+}
+
+//
+// NAVIGATION
+//
+
+.visEditorSidebar__titleContainer {
+ padding: $euiSizeS $euiSizeXL $euiSizeS $euiSizeS; // Extra padding on the right for the collapse button
+}
+
+.visEditorSidebar__indexPatternPlaceholder {
+ min-height: $euiSizeXXL;
+ border-bottom: $euiBorderThin;
+}
+
+.visEditorSidebar__nav,
+.visEditorSidebar__linkedSearch {
+ flex-grow: 0;
+}
+
+//
+// SECTIONS
+//
+
+.visEditorSidebar__section {
+ background-color: $euiColorEmptyShade;
+ padding: $euiSizeS;
+ border-radius: $euiBorderRadius;
+
+ + .visEditorSidebar__section {
+ margin-top: $euiSizeS;
+ }
+}
+
+// Collapsible section
+
+.visEditorSidebar__collapsible {
+ background-color: lightOrDarkTheme($euiPageBackgroundColor, $euiColorLightestShade);
+}
+
+.visEditorSidebar__collapsible--marginBottom {
+ margin-bottom: $euiSizeM;
+}
+
+//
+// FORMS
+//
+
+.visEditorSidebar__formRow {
+ display: flex;
+ align-items: center;
+ margin-top: $euiSizeM;
+}
+
+.visEditorSidebar__formLabel {
+ display: flex;
+ align-items: center;
+ flex: 1 1 40%;
+ padding-right: $euiSizeXS;
+}
+
+.visEditorSidebar__formControl {
+ display: flex;
+ align-items: center;
+ flex: 1 1 60%;
+}
+
+.visEditorSidebar__aggGroupAccordionButtonContent {
+ font-size: $euiFontSizeS;
+
+ span {
+ color: $euiColorDarkShade;
+ }
+}
+
+.visEditorSidebar__controls {
+ border-top: $euiBorderThin;
+ padding: $euiSizeS;
+ display: flex;
+ justify-content: flex-end;
+ align-items: center;
+
+ .visEditorSidebar__autoApplyButton {
+ margin-left: $euiSizeM;
+ }
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.tsx b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.tsx
new file mode 100644
index 000000000..02e7df2e8
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/config_panel.tsx
@@ -0,0 +1,258 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './config_panel.scss';
+
+import React, { useContext, useMemo, useState, useEffect, useCallback } from 'react';
+import { find } from 'lodash';
+import hjson from 'hjson';
+import Mustache from 'mustache';
+import {
+ EuiTabbedContent,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiSpacer,
+ EuiComboBox,
+ EuiPanel,
+ EuiIcon,
+ EuiTabbedContentTab,
+} from '@elastic/eui';
+import { reset as resetVisualizationConfig } from '../../slices/viualization_config_slice';
+import { getDefaultSpec } from '../visualization_specs/default_spec';
+import { TabContext } from '../../hooks';
+import { DefaultEditorControls } from './DefaultEditorControls';
+import { getVisType } from '../../../visualizations/charts/vis_types';
+import { ENABLED_VIS_TYPES } from '../../../../../common/constants/shared';
+
+const CONFIG_LAYOUT_TEMPLATE = `
+{
+ "layout": {},
+ "config": {
+ "scrollZoom": {{config.scrollZoom}},
+ "editable": {{config.editable}},
+ "staticPlot": {{config.staticPlot}},
+ "displayModeBar": {{config.displayModeBar}},
+ "responsive": {{config.responsive}},
+ "doubleClickDelay": {{config.doubleClickDelay}}
+ }
+}
+`;
+
+const HJSON_PARSE_OPTIONS = {
+ keepWsc: true,
+};
+
+const HJSON_STRINGIFY_OPTIONS = {
+ keepWsc: true,
+ condense: 0,
+ bracesSameLine: true,
+};
+
+interface PanelTabType {
+ id: string;
+ name: string;
+ mapTo: string;
+ editor: any;
+ section?: any;
+ content?: any;
+}
+
+export const ConfigPanel = ({ visualizations, setCurVisId, callback }: any) => {
+ const { tabId, curVisId, dispatch, changeVisualizationConfig, setToast } = useContext(
+ TabContext
+ );
+ const { data, vis } = visualizations;
+ const { userConfigs } = data;
+
+ const [vizConfigs, setVizConfigs] = useState({
+ dataConfig: {},
+ layoutConfig: userConfigs?.layoutConfig
+ ? hjson.stringify({ ...userConfigs.layoutConfig }, HJSON_STRINGIFY_OPTIONS)
+ : getDefaultSpec(),
+ availabilityConfig: {},
+ });
+
+ useEffect(() => {
+ setVizConfigs({
+ ...userConfigs,
+ layoutConfig: userConfigs?.layoutConfig
+ ? hjson.stringify({ ...userConfigs.layoutConfig }, HJSON_STRINGIFY_OPTIONS)
+ : getDefaultSpec(),
+ });
+ if (callback) {
+ callback(() => switchToAvailability());
+ }
+ }, [userConfigs, curVisId]);
+
+ const getParsedLayoutConfig = useCallback(
+ (hjsonConfig) =>
+ JSON.parse(
+ Mustache.render(CONFIG_LAYOUT_TEMPLATE, hjson.parse(hjsonConfig, HJSON_PARSE_OPTIONS))
+ ),
+ []
+ );
+
+ const handleConfigUpdate = useCallback(() => {
+ try {
+ dispatch(
+ changeVisualizationConfig({
+ tabId,
+ vizId: curVisId,
+ data: {
+ ...{
+ ...vizConfigs,
+ layoutConfig: hjson.parse(vizConfigs.layoutConfig),
+ },
+ },
+ })
+ );
+ } catch (e: any) {
+ setToast(`Invalid visualization configurations. error: ${e.message}`, 'danger');
+ }
+ }, [tabId, vizConfigs, changeVisualizationConfig, dispatch, setToast, curVisId]);
+
+ const handleConfigChange = (configSchema: string) => {
+ return (configChanges: any) => {
+ setVizConfigs((staleState) => {
+ return {
+ ...staleState,
+ [configSchema]: configChanges,
+ };
+ });
+ };
+ };
+
+ const params = useMemo(() => {
+ return {
+ dataConfig: {
+ visualizations,
+ curVisId,
+ onConfigChange: handleConfigChange('dataConfig'),
+ vizState: vizConfigs.dataConfig,
+ },
+ layoutConfig: {
+ onConfigEditorChange: handleConfigChange('layoutConfig'),
+ spec: vizConfigs.layoutConfig,
+ setToast,
+ },
+ availabilityConfig: {
+ visualizations,
+ curVisId,
+ onConfigChange: handleConfigChange('availabilityConfig'),
+ vizState: vizConfigs.availabilityConfig,
+ },
+ };
+ }, [visualizations, vizConfigs, setToast, curVisId]);
+
+ const tabs: EuiTabbedContentTab[] = useMemo(() => {
+ return vis.editorConfig.panelTabs.map((tab: PanelTabType) => {
+ const Editor = tab.editor;
+ return {
+ id: tab.id,
+ name: tab.name,
+ content: ,
+ };
+ });
+ }, [vis.editorConfig.panelTabs, params]);
+
+ const [currTabId, setCurrTabId] = useState(tabs[0].id);
+
+ const switchToAvailability = () => {
+ setCurrTabId('availability-panel');
+ };
+
+ const onTabClick = (selectedTab: EuiTabbedContentTab) => {
+ setCurrTabId(selectedTab.id);
+ };
+
+ const handleDiscardConfig = () => {
+ dispatch(
+ resetVisualizationConfig({
+ tabId,
+ })
+ );
+ };
+
+ const memorizedVisualizationTypes = useMemo(() => {
+ return ENABLED_VIS_TYPES.map((vs: string) => {
+ const visDefinition = getVisType(vs);
+ return {
+ ...visDefinition,
+ };
+ });
+ }, []);
+
+ const vizSelectableItemRenderer = (option) => {
+ const { iconType, label } = option;
+
+ return (
+
+
+
+ {label}
+
+ );
+ };
+
+ const getSelectedVisDById = useCallback(
+ (visId) => {
+ return find(memorizedVisualizationTypes, (v) => {
+ return v.id === visId;
+ });
+ },
+ [memorizedVisualizationTypes]
+ );
+
+ const vizTypeList = useMemo(() => {
+ return memorizedVisualizationTypes.filter((type) => type.id !== 'horizontal_bar');
+ }, [memorizedVisualizationTypes]);
+
+ return (
+ <>
+
+
+
+ {
+ setCurVisId(visType[0].id);
+ }}
+ fullWidth
+ renderOption={vizSelectableItemRenderer}
+ />
+
+
+
+
+ tab.id === currTabId) || tabs[0]}
+ onTabClick={onTabClick}
+ />
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/config_panel/index.ts b/dashboards-observability/public/components/explorer/visualizations/config_panel/index.ts
new file mode 100644
index 000000000..4c1f8be6e
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/config_panel/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { ConfigPanel } from './config_panel';
diff --git a/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/__snapshots__/count_distribution.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/__snapshots__/count_distribution.test.tsx.snap
new file mode 100644
index 000000000..83fe02a99
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/__snapshots__/count_distribution.test.tsx.snap
@@ -0,0 +1,357 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Count distribution component Renders count distribution component with data 1`] = `
+
+
+
+
+
+
+
+`;
+
+exports[`Count distribution component Renders count distribution component with data 2`] = `
+
+
+
+
+
+
+
+`;
+
+exports[`Count distribution component Renders empty count distribution component 1`] = ` `;
diff --git a/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/count_distribution.test.tsx b/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/count_distribution.test.tsx
new file mode 100644
index 000000000..9ae80ea7c
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/count_distribution/__tests__/count_distribution.test.tsx
@@ -0,0 +1,43 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { CountDistribution } from '../count_distribution';
+import { SAMPLE_VISUALIZATIONS } from '../../../../../../test/event_analytics_constants';
+
+describe('Count distribution component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders empty count distribution component', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('Renders count distribution component with data', async () => {
+
+ const wrapper = mount(
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/count_distribution/count_distribution.tsx b/dashboards-observability/public/components/explorer/visualizations/count_distribution/count_distribution.tsx
new file mode 100644
index 000000000..683873b5f
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/count_distribution/count_distribution.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { LONG_CHART_COLOR } from '../../../../../common/constants/shared';
+import { Plt } from '../../../visualizations/plotly/plot';
+
+export const CountDistribution = ({ countDistribution }: any) => {
+ if (
+ !countDistribution ||
+ !countDistribution.data ||
+ !countDistribution.metadata ||
+ !countDistribution.metadata.fields
+ )
+ return null;
+
+ const {
+ data,
+ metadata: { fields },
+ } = countDistribution;
+
+ const finalData = [
+ {
+ x: [...data[fields[1].name]],
+ y: [...data[fields[0].name]],
+ type: 'bar',
+ name: fields[0],
+ orientation: 'v',
+ },
+ ];
+
+ return (
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/count_distribution/index.ts b/dashboards-observability/public/components/explorer/visualizations/count_distribution/index.ts
new file mode 100644
index 000000000..7d6456ee0
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/count_distribution/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './count_distribution';
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/datapanel.scss b/dashboards-observability/public/components/explorer/visualizations/datapanel.scss
new file mode 100644
index 000000000..9e97b1058
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/datapanel.scss
@@ -0,0 +1,41 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsInnerIndexPatternDataPanel {
+ width: 100%;
+ height: 100%;
+ padding: $euiSize $euiSize 0;
+}
+
+.lnsInnerIndexPatternDataPanel__header {
+ display: flex;
+ align-items: center;
+ margin-bottom: $euiSizeS;
+}
+
+.lnsInnerIndexPatternDataPanel__fieldItems {
+ // Quick fix for making sure the shadow and focus rings are visible outside the accordion bounds
+ padding: $euiSizeXS;
+}
+
+.lnsInnerIndexPatternDataPanel__textField {
+ @include euiFormControlLayoutPadding(1, 'right');
+ @include euiFormControlLayoutPadding(1, 'left');
+}
+
+.lnsInnerIndexPatternDataPanel__filterType {
+ font-size: $euiFontSizeS;
+ padding: $euiSizeS;
+ border-bottom: 1px solid $euiColorLightestShade;
+}
+
+.lnsInnerIndexPatternDataPanel__filterTypeInner {
+ display: flex;
+ align-items: center;
+
+ .lnsFieldListPanel__fieldIcon {
+ margin-right: $euiSizeS;
+ }
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/datapanel.tsx b/dashboards-observability/public/components/explorer/visualizations/datapanel.tsx
new file mode 100644
index 000000000..deccff299
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/datapanel.tsx
@@ -0,0 +1,72 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './datapanel.scss';
+import './field_item.scss';
+import React, { useState } from 'react';
+import _ from 'lodash';
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFormControlLayout,
+ EuiSpacer
+} from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+import { FieldList } from './fieldList';
+
+export const DataPanel = (props: any) => {
+
+ const fields = props.explorerFields?.availableFields;
+
+ const [searchTerm, setSearchTerm] = useState('');
+
+ return (
+
+
+ {},
+ }}
+ >
+ {
+ setSearchTerm(e.target.value);
+ }}
+ aria-label={i18n.translate('xpack.lens.indexPatterns.filterByNameAriaLabel', {
+ defaultMessage: 'Search fields',
+ })}
+ />
+
+
+
+
+ searchTerm === '' || field.name.indexOf(searchTerm) !== -1) }
+ />
+
+
+ );
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.scss b/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.scss
new file mode 100644
index 000000000..cc5399d13
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.scss
@@ -0,0 +1,59 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+@import '../variables';
+@import '../mixins';
+
+.lnsDragDrop {
+ transition: background-color $euiAnimSpeedFast ease-in-out, border-color $euiAnimSpeedFast ease-in-out;
+}
+
+// Draggable item
+.lnsDragDrop-isDraggable {
+ @include lnsDraggable;
+ @include lnsDragDropHover;
+
+ // Include a possible nested button like when using FieldButton
+ > .kbnFieldButton__button {
+ cursor: grab;
+ }
+
+ &:focus {
+ @include euiFocusRing;
+ }
+}
+
+// Draggable item when it is moving
+.lnsDragDrop-isHidden {
+ opacity: 0;
+}
+
+// Drop area
+.lnsDragDrop-isDroppable {
+ @include lnsDroppable;
+}
+
+// Drop area when there's an item being dragged
+.lnsDragDrop-isDropTarget {
+ @include lnsDroppableActive;
+}
+
+// Drop area while hovering with item
+.lnsDragDrop-isActiveDropTarget {
+ @include lnsDroppableActiveHover;
+}
+
+// Drop area that is not allowed for current item
+.lnsDragDrop-isNotDroppable {
+ @include lnsDroppableNotAllowed;
+}
+
+// Drop area will be replacing existing content
+.lnsDragDrop-isReplacing {
+ &,
+ .lnsLayerPanel__triggerLink {
+ text-decoration: line-through;
+ }
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.tsx b/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.tsx
new file mode 100644
index 000000000..2d47eb175
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/drag_drop/drag_drop.tsx
@@ -0,0 +1,249 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './drag_drop.scss';
+
+import React, { useState, useContext } from 'react';
+import classNames from 'classnames';
+import { DragContext } from './providers';
+// import { trackUiEvent } from '../lens_ui_telemetry';
+
+type DroppableEvent = React.DragEvent;
+
+/**
+ * A function that handles a drop event.
+ */
+export type DropHandler = (item: unknown) => void;
+
+/**
+ * The base props to the DragDrop component.
+ */
+interface BaseProps {
+ /**
+ * The CSS class(es) for the root element.
+ */
+ className?: string;
+
+ /**
+ * The event handler that fires when an item
+ * is dropped onto this DragDrop component.
+ */
+ onDrop?: DropHandler;
+
+ /**
+ * The value associated with this item, if it is draggable.
+ * If this component is dragged, this will be the value of
+ * "dragging" in the root drag/drop context.
+ */
+ value?: unknown;
+
+ /**
+ * Optional comparison function to check whether a value is the dragged one
+ */
+ isValueEqual?: (value1: unknown, value2: unknown) => boolean;
+
+ /**
+ * The React element which will be passed the draggable handlers
+ */
+ children: React.ReactElement;
+
+ /**
+ * Indicates whether or not the currently dragged item
+ * can be dropped onto this component.
+ */
+ droppable?: boolean;
+
+ /**
+ * Additional class names to apply when another element is over the drop target
+ */
+ getAdditionalClassesOnEnter?: () => string;
+
+ /**
+ * The optional test subject associated with this DOM element.
+ */
+ 'data-test-subj'?: string;
+
+ /**
+ * Indicates to the user whether the currently dragged item
+ * will be moved or copied
+ */
+ dragType?: 'copy' | 'move';
+
+ /**
+ * Indicates to the user whether the drop action will
+ * replace something that is existing or add a new one
+ */
+ dropType?: 'add' | 'replace';
+}
+
+/**
+ * The props for a draggable instance of that component.
+ */
+interface DraggableProps extends BaseProps {
+ /**
+ * Indicates whether or not this component is draggable.
+ */
+ draggable: true;
+ /**
+ * The label, which should be attached to the drag event, and which will e.g.
+ * be used if the element will be dropped into a text field.
+ */
+ label: string;
+}
+
+/**
+ * The props for a non-draggable instance of that component.
+ */
+interface NonDraggableProps extends BaseProps {
+ /**
+ * Indicates whether or not this component is draggable.
+ */
+ draggable?: false;
+}
+
+type Props = DraggableProps | NonDraggableProps;
+
+/**
+ * A draggable / droppable item. Items can be both draggable and droppable at
+ * the same time.
+ *
+ * @param props
+ */
+
+export const DragDrop = (props: Props) => {
+ const { dragging, setDragging } = useContext(DragContext);
+ const { value, draggable, droppable, isValueEqual } = props;
+ return (
+
+ );
+};
+
+const DragDropInner = React.memo(function DragDropInner(
+ props: Props & {
+ dragging: unknown;
+ setDragging: (dragging: unknown) => void;
+ isDragging: boolean;
+ isNotDroppable: boolean;
+ }
+) {
+ const [state, setState] = useState({
+ isActive: false,
+ dragEnterClassNames: '',
+ });
+ const {
+ className,
+ onDrop,
+ value,
+ children,
+ droppable,
+ draggable,
+ dragging,
+ setDragging,
+ isDragging,
+ isNotDroppable,
+ dragType = 'copy',
+ dropType = 'add',
+ } = props;
+
+ const isMoveDragging = isDragging && dragType === 'move';
+
+ const classes = classNames(
+ 'lnsDragDrop',
+ {
+ 'lnsDragDrop-isDraggable': draggable,
+ 'lnsDragDrop-isDragging': isDragging,
+ 'lnsDragDrop-isHidden': isMoveDragging,
+ 'lnsDragDrop-isDroppable': !draggable,
+ 'lnsDragDrop-isDropTarget': droppable,
+ 'lnsDragDrop-isActiveDropTarget': droppable && state.isActive,
+ 'lnsDragDrop-isNotDroppable': !isMoveDragging && isNotDroppable,
+ 'lnsDragDrop-isReplacing': droppable && state.isActive && dropType === 'replace',
+ },
+ className,
+ state.dragEnterClassNames
+ );
+
+ const dragStart = (e: DroppableEvent) => {
+ // Setting stopPropgagation causes Chrome failures, so
+ // we are manually checking if we've already handled this
+ // in a nested child, and doing nothing if so...
+ if (e.dataTransfer.getData('text')) {
+ return;
+ }
+
+ // We only can reach the dragStart method if the element is draggable,
+ // so we know we have DraggableProps if we reach this code.
+ e.dataTransfer.setData('text', (props as DraggableProps).label);
+
+ // Chrome causes issues if you try to render from within a
+ // dragStart event, so we drop a setTimeout to avoid that.
+ setTimeout(() => setDragging(value));
+ };
+
+ const dragEnd = (e: DroppableEvent) => {
+ e.stopPropagation();
+ setDragging(undefined);
+ };
+
+ const dragOver = (e: DroppableEvent) => {
+ if (!droppable) {
+ return;
+ }
+
+ e.preventDefault();
+
+ // An optimization to prevent a bunch of React churn.
+ if (!state.isActive) {
+ setState({
+ ...state,
+ isActive: true,
+ dragEnterClassNames: props.getAdditionalClassesOnEnter
+ ? props.getAdditionalClassesOnEnter()
+ : '',
+ });
+ }
+ };
+
+ const dragLeave = () => {
+ setState({ ...state, isActive: false, dragEnterClassNames: '' });
+ };
+
+ const drop = (e: DroppableEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ setState({ ...state, isActive: false, dragEnterClassNames: '' });
+ setDragging(undefined);
+
+ if (onDrop && droppable) {
+ // trackUiEvent('drop_total');
+ onDrop(dragging);
+ }
+ };
+
+ return React.cloneElement(children, {
+ 'data-test-subj': props['data-test-subj'] || 'lnsDragDrop',
+ className: classNames(children.props.className, classes),
+ onDragOver: dragOver,
+ onDragLeave: dragLeave,
+ onDrop: drop,
+ draggable,
+ onDragEnd: dragEnd,
+ onDragStart: dragStart,
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/drag_drop/index.ts b/dashboards-observability/public/components/explorer/visualizations/drag_drop/index.ts
new file mode 100644
index 000000000..e2a5489cd
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/drag_drop/index.ts
@@ -0,0 +1,7 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './providers';
+export * from './drag_drop';
diff --git a/dashboards-observability/public/components/explorer/visualizations/drag_drop/providers.tsx b/dashboards-observability/public/components/explorer/visualizations/drag_drop/providers.tsx
new file mode 100644
index 000000000..d5105277b
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/drag_drop/providers.tsx
@@ -0,0 +1,85 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState, useMemo } from 'react';
+
+/**
+ * The shape of the drag / drop context.
+ */
+export interface DragContextState {
+ /**
+ * The item being dragged or undefined.
+ */
+ dragging: unknown;
+
+ /**
+ * Set the item being dragged.
+ */
+ setDragging: (dragging: unknown) => void;
+}
+
+/**
+ * The drag / drop context singleton, used like so:
+ *
+ * const { dragging, setDragging } = useContext(DragContext);
+ */
+export const DragContext = React.createContext({
+ dragging: undefined,
+ setDragging: () => {},
+});
+
+/**
+ * The argument to DragDropProvider.
+ */
+export interface ProviderProps {
+ /**
+ * The item being dragged. If unspecified, the provider will
+ * behave as if it is the root provider.
+ */
+ dragging: unknown;
+
+ /**
+ * Sets the item being dragged. If unspecified, the provider
+ * will behave as if it is the root provider.
+ */
+ setDragging: (dragging: unknown) => void;
+
+ /**
+ * The React children.
+ */
+ children: React.ReactNode;
+}
+
+/**
+ * A React provider that tracks the dragging state. This should
+ * be placed at the root of any React application that supports
+ * drag / drop.
+ *
+ * @param props
+ */
+export function RootDragDropProvider({ children }: { children: React.ReactNode }) {
+ const [state, setState] = useState<{ dragging: unknown }>({
+ dragging: undefined,
+ });
+ const setDragging = useMemo(() => (dragging: unknown) => setState({ dragging }), [setState]);
+
+ return (
+
+ {children}
+
+ );
+}
+
+/**
+ * A React drag / drop provider that derives its state from a RootDragDropProvider. If
+ * part of a React application is rendered separately from the root, this provider can
+ * be used to enable drag / drop functionality within the disconnected part.
+ *
+ * @param props
+ */
+export function ChildDragDropProvider({ dragging, setDragging, children }: ProviderProps) {
+ const value = useMemo(() => ({ dragging, setDragging }), [setDragging, dragging]);
+ return {children} ;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/drag_drop/readme.md b/dashboards-observability/public/components/explorer/visualizations/drag_drop/readme.md
new file mode 100644
index 000000000..8d11cb622
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/drag_drop/readme.md
@@ -0,0 +1,69 @@
+# Drag / Drop
+
+This is a simple drag / drop mechanism that plays nice with React.
+
+We aren't using EUI or another library, due to the fact that Lens visualizations and datasources may or may not be written in React. Even visualizations which are written in React will end up having their own ReactDOM.render call, and in that sense will be a standalone React application. We want to enable drag / drop across React and native DOM boundaries.
+
+## Getting started
+
+First, place a RootDragDropProvider at the root of your application.
+
+```js
+
+ ... your app here ...
+
+```
+
+If you have a child React application (e.g. a visualization), you will need to pass the drag / drop context down into it. This can be obtained like so:
+
+```js
+const context = useContext(DragContext);
+```
+
+In your child application, place a `ChildDragDropProvider` at the root of that, and spread the context into it:
+
+```js
+
+ ... your child app here ...
+
+```
+
+This enables your child application to share the same drag / drop context as the root application.
+
+## Dragging
+
+An item can be both draggable and droppable at the same time, but for simplicity's sake, we'll treat these two cases separately.
+
+To enable dragging an item, use `DragDrop` with both a `draggable` and a `value` attribute.
+
+```js
+
+ {fields.map(f => (
+
+ {f.name}
+
+ ))}
+
+```
+
+## Dropping
+
+To enable dropping, use `DragDrop` with both a `droppable` attribute and an `onDrop` handler attribute. Droppable should only be set to true if there is an item being dragged, and if a drop of the dragged item is supported.
+
+```js
+const { dragging } = useContext(DragContext);
+
+return (
+ onChange([...items, item])}
+ >
+ {items.map(x => {x.name}
)}
+
+);
+```
+
+## Limitations
+
+Currently this is a very simple drag / drop mechanism. We don't support reordering out of the box, though it could probably be built on top of this solution without modification of the core.
diff --git a/dashboards-observability/public/components/explorer/visualizations/fieldList.tsx b/dashboards-observability/public/components/explorer/visualizations/fieldList.tsx
new file mode 100644
index 000000000..0375cd680
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/fieldList.tsx
@@ -0,0 +1,35 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FieldsAccordion } from './fields_accordion';
+
+export const FieldList = (
+ {
+ fields,
+ id
+ }: any
+) => {
+
+ return (
+
+ );
+};
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/field_item.scss b/dashboards-observability/public/components/explorer/visualizations/field_item.scss
new file mode 100644
index 000000000..670884bb9
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/field_item.scss
@@ -0,0 +1,53 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsFieldItem {
+ .lnsFieldItem__infoIcon {
+ visibility: hidden;
+ opacity: 0;
+ }
+
+ &:hover:not([class*='isActive']) {
+ cursor: grab;
+
+ .lnsFieldItem__infoIcon {
+ visibility: visible;
+ opacity: 1;
+ transition: opacity $euiAnimSpeedFast ease-in-out 1s;
+ }
+ }
+}
+
+.lnsFieldItem--missing {
+ background: lightOrDarkTheme(transparentize($euiColorMediumShade, .9), $euiColorEmptyShade);
+ color: $euiColorDarkShade;
+}
+
+.lnsFieldItem__topValue {
+ margin-bottom: $euiSizeS;
+
+ &:last-of-type {
+ margin-bottom: 0;
+ }
+}
+
+.lnsFieldItem__topValueProgress {
+ background-color: $euiColorLightestShade;
+
+ // sass-lint:disable-block no-vendor-prefixes
+ &::-webkit-progress-bar {
+ background-color: $euiColorLightestShade;
+ }
+}
+
+.lnsFieldItem__fieldPanel {
+ min-width: 260px;
+ max-width: 300px;
+}
+
+.lnsFieldItem__buttonGroup {
+ // Enforce lowercase for buttons or else some browsers inherit all caps from flyout title
+ text-transform: none;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/field_item.tsx b/dashboards-observability/public/components/explorer/visualizations/field_item.tsx
new file mode 100644
index 000000000..0405b3df0
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/field_item.tsx
@@ -0,0 +1,108 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './field_item.scss';
+
+import React, { useState } from 'react';
+import {
+ EuiIconTip,
+ EuiPopover
+} from '@elastic/eui';
+import { i18n } from '@osd/i18n';
+import { EuiHighlight } from '@elastic/eui';
+import { FieldButton } from '../../common/field_button';
+import { DragDrop } from './drag_drop';
+import { LensFieldIcon } from './lens_field_icon';
+
+import { debouncedComponent } from '../../common/debounced_component';
+
+function wrapOnDot(str?: string) {
+ // u200B is a non-width white-space character, which allows
+ // the browser to efficiently word-wrap right after the dot
+ // without us having to draw a lot of extra DOM elements, etc
+ return str ? str.replace(/\./g, '.\u200B') : '';
+}
+
+export const InnerFieldItem = function InnerFieldItem(props: any) {
+ const {
+ field,
+ highlight,
+ exists,
+ hideDetails,
+ } = props;
+
+ const [infoIsOpen, setOpen] = useState(false);
+
+ function togglePopover() {}
+
+ const lensFieldIcon = ;
+ const lensInfoIcon = (
+
+ );
+ return (
+ ('.application') || undefined}
+ button={
+
+
+ {wrapOnDot(field.name)}
+
+ }
+ fieldInfoIcon={lensInfoIcon}
+ />
+
+ }
+ isOpen={infoIsOpen}
+ closePopover={() => setOpen(false)}
+ anchorPosition="rightUp"
+ panelClassName="lnsFieldItem__fieldPanel"
+ >
+
+ );
+};
+
+export const FieldItem = debouncedComponent(InnerFieldItem);
diff --git a/dashboards-observability/public/components/explorer/visualizations/field_list.scss b/dashboards-observability/public/components/explorer/visualizations/field_list.scss
new file mode 100644
index 000000000..33faa8dfe
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/field_list.scss
@@ -0,0 +1,25 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * 1. Don't cut off the shadow of the field items
+ */
+
+.lnsIndexPatternFieldList {
+ @include euiOverflowShadow;
+ @include euiScrollBar;
+ margin-left: -$euiSize; /* 1 */
+ position: relative;
+ flex-grow: 1;
+ overflow: auto;
+}
+
+.lnsIndexPatternFieldList__accordionContainer {
+ padding-top: $euiSizeS;
+ position: absolute;
+ top: 0;
+ left: $euiSize; /* 1 */
+ right: $euiSizeXS; /* 1 */
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/fields_accordion.tsx b/dashboards-observability/public/components/explorer/visualizations/fields_accordion.tsx
new file mode 100644
index 000000000..955558d3d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/fields_accordion.tsx
@@ -0,0 +1,75 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './datapanel.scss';
+import React, { memo, useCallback } from 'react';
+import { i18n } from '@osd/i18n';
+import {
+ EuiText,
+ EuiNotificationBadge,
+ EuiSpacer,
+ EuiAccordion,
+ EuiLoadingSpinner,
+ EuiIconTip,
+} from '@elastic/eui';
+import { FieldItem } from './field_item';
+
+export const InnerFieldsAccordion = function InnerFieldsAccordion({
+ id,
+ label,
+ isFiltered,
+ paginatedFields,
+ showExistenceFetchError,
+}: any) {
+ const renderField = useCallback(
+ (field) => (
+
+ ),
+ []
+ );
+
+ return (
+
+ {label}
+
+ }
+ extraAction={
+ showExistenceFetchError ? (
+
+ ) : true ? (
+
+ {paginatedFields?.length}
+
+ ) : (
+
+ )
+ }
+ >
+
+
+ {paginatedFields && paginatedFields.map(renderField)}
+
+
+ );
+};
+
+export const FieldsAccordion = memo(InnerFieldsAccordion);
diff --git a/dashboards-observability/public/components/explorer/visualizations/frame_layout.scss b/dashboards-observability/public/components/explorer/visualizations/frame_layout.scss
new file mode 100644
index 000000000..8d07d5a0a
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/frame_layout.scss
@@ -0,0 +1,66 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+$lnsPanelMinWidth: $euiSize * 18;
+
+// These sizes also match canvas' page thumbnails for consistency
+$lnsSuggestionHeight: 100px;
+$lnsSuggestionWidth: 150px;
+
+.lnsFrameLayout {
+ padding: 0;
+ // position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ overflow: hidden;
+ flex-direction: column;
+}
+
+.lnsFrameLayout__pageContent {
+ display: flex;
+ overflow: hidden;
+ flex-grow: 1;
+}
+
+.lnsFrameLayout__pageBody {
+ @include euiScrollBar;
+ min-width: $lnsPanelMinWidth + $euiSizeXL;
+ max-height: 100%;
+ overflow: hidden auto;
+ // Leave out bottom padding so the suggestions scrollbar stays flush to window edge
+ // Leave out left padding so the left sidebar's focus states are visible outside of content bounds
+ // This also means needing to add same amount of margin to page content and suggestion items
+ padding: $euiSize $euiSize 0;
+
+ &:first-child {
+ padding-left: $euiSize;
+ }
+}
+
+.lnsFrameLayout__sidebar {
+ margin: 0 16px 0;
+ flex: 1 0 18%;
+ min-width: $lnsPanelMinWidth + $euiSize;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+}
+
+.lnsFrameLayout__sidebar--right {
+ flex-basis: 25%;
+ background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk);
+ min-width: $lnsPanelMinWidth + $euiSizeXL;
+ max-width: $euiFormMaxWidth + $euiSizeXXL;
+ max-height: 100%;
+
+ .lnsConfigPanel {
+ @include euiScrollBar;
+ padding: $euiSize 0 $euiSize $euiSize;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ }
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/frame_layout.tsx b/dashboards-observability/public/components/explorer/visualizations/frame_layout.tsx
new file mode 100644
index 000000000..86781b213
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/frame_layout.tsx
@@ -0,0 +1,31 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './frame_layout.scss';
+
+import React from 'react';
+import { EuiPage, EuiPageSideBar, EuiPageBody } from '@elastic/eui';
+
+export interface FrameLayoutProps {
+ dataPanel: React.ReactNode;
+ configPanel?: React.ReactNode;
+ suggestionsPanel?: React.ReactNode;
+ workspacePanel?: React.ReactNode;
+}
+
+export function FrameLayout(props: FrameLayoutProps) {
+ return (
+
+
+
+ {props.workspacePanel}
+
+
+ {props.configPanel}
+
+
+
+ );
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/index.tsx b/dashboards-observability/public/components/explorer/visualizations/index.tsx
new file mode 100644
index 000000000..6ae2a5704
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/index.tsx
@@ -0,0 +1,85 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './app.scss';
+
+import _ from 'lodash';
+
+import React from 'react';
+import { EuiResizableContainer } from '@elastic/eui';
+import { SELECTED_TIMESTAMP } from '../../../../common/constants/explorer';
+import { IField, IQuery, IVisualizationContainerProps } from '../../../../common/types/explorer';
+import { WorkspacePanel } from './workspace_panel';
+import { ConfigPanel } from './config_panel';
+import { Sidebar } from '../sidebar';
+
+interface IExplorerVisualizationsProps {
+ query: IQuery;
+ curVisId: string;
+ setCurVisId: (visId: string) => void;
+ explorerVis: any;
+ explorerFields: IField[];
+ explorerData: any;
+ handleAddField: (field: IField) => void;
+ handleRemoveField: (field: IField) => void;
+ visualizations: IVisualizationContainerProps;
+ handleOverrideTimestamp: (field: IField) => void;
+ callback?: any;
+}
+
+export const ExplorerVisualizations = ({
+ query,
+ curVisId,
+ setCurVisId,
+ explorerVis,
+ explorerFields,
+ explorerData,
+ handleAddField,
+ handleRemoveField,
+ visualizations,
+ handleOverrideTimestamp,
+ callback,
+}: IExplorerVisualizationsProps) => {
+ return (
+
+ {(EuiResizablePanel, EuiResizableButton) => (
+ <>
+
+
+ handleAddField(field)}
+ handleRemoveField={(field: IField) => handleRemoveField(field)}
+ isFieldToggleButtonDisabled={true}
+ />
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/lens_field_icon.tsx b/dashboards-observability/public/components/explorer/visualizations/lens_field_icon.tsx
new file mode 100644
index 000000000..59c947bce
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/lens_field_icon.tsx
@@ -0,0 +1,20 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { FieldIcon } from '../../common/field_icon';
+export function LensFieldIcon({ type, ...rest }) {
+ return (
+
+ );
+}
+
+export function normalizeOperationDataType(type) {
+ return type === 'document' ? 'number' : type;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap b/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap
new file mode 100644
index 000000000..7fc0731ee
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap
@@ -0,0 +1,198 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Shared components Renders empty placeholder component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No results found
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Shared components Renders tool bar button component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ testing
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/shared_components.test.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/shared_components.test.tsx
new file mode 100644
index 000000000..89fd64289
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/__tests__/shared_components.test.tsx
@@ -0,0 +1,43 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { waitFor } from '@testing-library/react';
+import { EmptyPlaceholder } from '../empty_placeholder';
+import { LensIconChartBar } from '../../../../visualizations/assets/chart_bar';
+import { ToolbarButton } from '../toolbar_button';
+
+describe('Shared components', () => {
+ configure({ adapter: new Adapter() });
+
+ it('Renders empty placeholder component', async () => {
+ const wrapper = mount( );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+
+ it('Renders tool bar button component', async () => {
+ const handleClick = jest.fn();
+ const WrappedComponent = () => testing
;
+
+ const wrapper = mount(
+
+
+
+ );
+
+ wrapper.update();
+
+ await waitFor(() => {
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/empty_placeholder.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/empty_placeholder.tsx
new file mode 100644
index 000000000..30e316ace
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/empty_placeholder.tsx
@@ -0,0 +1,23 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui';
+import { FormattedMessage } from '@osd/i18n/react';
+
+export const EmptyPlaceholder = (props: {icon: string}) => (
+ <>
+
+
+
+
+
+
+
+ >
+);
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/index.ts b/dashboards-observability/public/components/explorer/visualizations/shared_components/index.ts
new file mode 100644
index 000000000..dfbd82f35
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export * from './empty_placeholder';
+export { ToolbarPopoverProps, ToolbarPopover } from './toolbar_popover';
+export { ToolbarButtonProps, ToolbarButton } from './toolbar_button';
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/index.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/index.tsx
new file mode 100644
index 000000000..1238af2fe
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/index.tsx
@@ -0,0 +1 @@
+export { PlotlyVizEditor } from './plotly_viz_editor';
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_actions.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_actions.tsx
new file mode 100644
index 000000000..e918d7b74
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_actions.tsx
@@ -0,0 +1,77 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Modifications Copyright OpenSearch Contributors. See
+ * GitHub history for details.
+ */
+
+import React, { useState, useCallback } from 'react';
+import { EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem, EuiPopover } from '@elastic/eui';
+import { FormattedMessage } from '@osd/i18n/react';
+
+interface PlotlyEditorActionsMenuProps {
+ formatHJson(): void;
+}
+
+function PlotlyEditorActionsMenu({ formatHJson }: PlotlyEditorActionsMenuProps) {
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+
+ const onButtonClick = useCallback(() => setIsPopoverOpen((isOpen) => !isOpen), []);
+ const onHJsonCLick = useCallback(() => {
+ formatHJson();
+ setIsPopoverOpen(false);
+ }, [formatHJson]);
+
+ const closePopover = useCallback(() => setIsPopoverOpen(false), []);
+
+ const button = ;
+
+ const items = [
+
+
+ ,
+ ];
+
+ return (
+
+ );
+}
+
+export { PlotlyEditorActionsMenu };
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_editor.scss b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_editor.scss
new file mode 100644
index 000000000..709aaa203
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_editor.scss
@@ -0,0 +1,22 @@
+.visEditor--vega {
+ .visEditorSidebar__config {
+ padding: 0;
+ }
+}
+
+.vgaEditor {
+ @include euiBreakpoint('xs', 's', 'm') {
+ @include euiScrollBar;
+ max-height: $euiSize * 15;
+ overflow-y: auto;
+ }
+}
+
+.vgaEditor__aceEditorActions {
+ position: absolute;
+ z-index: $euiZLevel1;
+ top: $euiSizeS;
+ // Adjust for sidebar collapse button
+ right: $euiSizeXXL;
+ line-height: 1;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_vis.scss b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_vis.scss
new file mode 100644
index 000000000..12108c7ba
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_vis.scss
@@ -0,0 +1,146 @@
+.vgaVis {
+ display: flex;
+ flex: 1 1 100%;
+ position: relative;
+ // flex-direction determined by js
+}
+
+.vgaVis__view {
+ z-index: 0;
+ flex: 1 1 100%;
+
+ display: block;
+ max-width: 100%;
+ max-height: 100%;
+ width: 100%;
+ height: 100%;
+
+ // BUG #23514: Make sure Vega doesn't display the controls in two places
+ .vega-bindings {
+ // sass-lint:disable no-important
+ display: none !important;
+ }
+}
+
+.vgaVis__controls {
+ @include euiFontSizeS;
+ display: flex;
+
+ &:not(:empty) {
+ padding: $euiSizeS 0; // Adding a little bit of padding helps with the unnecessary scrollbars
+ }
+
+ &.vgaVis__controls--column {
+ flex-direction: column;
+ }
+
+ &.vgaVis__controls--row {
+ flex-direction: row;
+
+ > .vega-bind {
+ flex-grow: 1;
+ }
+ }
+
+ > .vega-bind {
+ .vega-bind-name {
+ display: inline-block;
+ width: $euiSizeM * 10 - $euiSize;
+ }
+
+ input[type='range'] {
+ width: $euiSizeM * 10;
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ label {
+ margin: 0 0 0 $euiSizeS;
+ }
+
+ select {
+ max-width: $euiSize * 10;
+ }
+
+ .vega-bind-radio label {
+ margin: 0 $euiSizeS 0 $euiSizeXS;
+ }
+ }
+}
+
+// Messages
+
+.vgaVis__messages {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ margin: auto;
+ opacity: .8;
+ z-index: 1;
+ list-style: none;
+}
+
+.vgaVis__message {
+ margin: $euiSizeS;
+
+ .vgaVis__messageCode {
+ white-space: pre-wrap;
+ padding: $euiSizeS;
+ }
+}
+
+.vgaVis__message--warn .vgaVis__messageCode {
+ $calculatedBackgroundColor: tintOrShade($euiColorWarning, 90%, 70%);
+ background-color: $calculatedBackgroundColor;
+ color: makeHighContrastColor($euiColorWarning, $calculatedBackgroundColor);
+}
+
+.vgaVis__message--err .vgaVis__messageCode {
+ $calculateBackgroundColor: tintOrShade($euiColorDanger, 90%, 70%);
+ background-color: $calculateBackgroundColor;
+ color: makeHighContrastColor($euiColorDanger, $calculateBackgroundColor);
+}
+
+
+// Style tooltip popup (gets created dynamically at the top level if dashboard has a Vega vis)
+// Adapted from https://github.com/vega/vega-tooltip
+
+.vgaVis__tooltip {
+ max-width: 100%;
+ position: fixed;
+
+ h2 {
+ margin-bottom: $euiSizeS;
+ }
+
+ td {
+ @include euiTextTruncate;
+ padding-top: $euiSizeXS;
+ padding-bottom: $euiSizeXS;
+
+ &.key {
+ color: $euiColorMediumShade;
+ max-width: $euiSize * 10;
+ text-align: right;
+ padding-right: $euiSizeXS;
+ }
+
+ &.value {
+ max-width: $euiSizeL * 10;
+ text-align: left;
+ }
+ }
+
+
+ @media only screen and (max-width: map-get($euiBreakpoints, 'm')) {
+ td {
+ &.key {
+ max-width: $euiSize * 6;
+ }
+
+ &.value {
+ max-width: $euiSize * 10;
+ }
+ }
+ }
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_viz_editor.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_viz_editor.tsx
new file mode 100644
index 000000000..f16c7b69e
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/plotly_viz_editor/plotly_viz_editor.tsx
@@ -0,0 +1,101 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ */
+
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Modifications Copyright OpenSearch Contributors. See
+ * GitHub history for details.
+ */
+
+import './plotly_vis.scss';
+import './plotly_editor.scss';
+
+import React, { useCallback } from 'react';
+import { EuiCodeEditor } from '@elastic/eui';
+import compactStringify from 'json-stringify-pretty-compact';
+import hjson from 'hjson';
+import 'brace/mode/hjson';
+import { PlotlyEditorActionsMenu } from './plotly_actions';
+
+const aceOptions = {
+ maxLines: Infinity,
+ highlightActiveLine: false,
+ showPrintMargin: false,
+ tabSize: 2,
+ useSoftTabs: true,
+ wrap: true,
+};
+
+const hjsonStringifyOptions = {
+ bracesSameLine: true,
+ keepWsc: true,
+};
+
+function PlotlyVizEditor({ spec, onVizConfigChange, setToast, vizState, userConfigs = {} }: any) {
+ const formatHJson = useCallback(
+ () => onVizConfigChange(format(spec, hjson.stringify, hjsonStringifyOptions)),
+ [onVizConfigChange, spec]
+ );
+
+ const format = (
+ value: string,
+ stringify: typeof hjson.stringify | typeof compactStringify,
+ options?: any
+ ) => {
+ try {
+ const formattedSpec = hjson.parse(value, { legacyRoot: false, keepWsc: true });
+ return stringify(formattedSpec, options);
+ } catch (err) {
+ // This is a common case - user tries to format an invalid HJSON text
+ setToast(`Error formatting spec: '${err.message}`, 'danger');
+
+ return value;
+ }
+ };
+
+ return (
+
+
{
+ onVizConfigChange(config);
+ }}
+ value={spec}
+ setOptions={aceOptions}
+ isReadOnly={false}
+ />
+
+
+ );
+}
+
+export { PlotlyVizEditor };
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.scss b/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.scss
new file mode 100644
index 000000000..621cb9293
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.scss
@@ -0,0 +1,65 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsToolbarButton {
+ line-height: $euiButtonHeight; // Keeps alignment of text and chart icon
+ background-color: $euiColorEmptyShade;
+
+ // Some toolbar buttons are just icons, but EuiButton comes with margin and min-width that need to be removed
+ min-width: 0;
+
+ &[class*='--text'] {
+ // Lighten the border color for all states
+ border-color: $euiBorderColor !important; // sass-lint:disable-line no-important
+ }
+
+ &[class*='isDisabled'] {
+ // There is a popover `pointer-events: none` that messes with the not-allowed cursor
+ pointer-events: initial;
+ }
+
+ .lnsToolbarButton__text > svg {
+ margin-top: -1px; // Just some weird alignment issue when icon is the child not the `iconType`
+ }
+
+ .lnsToolbarButton__text:empty {
+ margin: 0;
+ }
+
+ // Toolbar buttons don't look good with centered text when fullWidth
+ &[class*='fullWidth'] {
+ text-align: left;
+
+ .lnsToolbarButton__content {
+ justify-content: space-between;
+ }
+ }
+
+}
+
+.lnsToolbarButton--groupLeft {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.lnsToolbarButton--groupCenter {
+ border-radius: 0;
+ border-left: none;
+}
+
+.lnsToolbarButton--groupRight {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-left: none;
+}
+
+.lnsToolbarButton--bold {
+ font-weight: $euiFontWeightBold;
+}
+
+.lnsToolbarButton--s {
+ box-shadow: none !important; // sass-lint:disable-line no-important
+ font-size: $euiFontSizeS;
+}
diff --git a/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.tsx b/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.tsx
new file mode 100644
index 000000000..99d0aca64
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/shared_components/toolbar_button.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './toolbar_button.scss';
+import React from 'react';
+import classNames from 'classnames';
+import { EuiButton, PropsOf, EuiButtonProps } from '@elastic/eui';
+
+const groupPositionToClassMap = {
+ none: null,
+ left: 'lnsToolbarButton--groupLeft',
+ center: 'lnsToolbarButton--groupCenter',
+ right: 'lnsToolbarButton--groupRight',
+};
+
+export type ToolbarButtonProps = PropsOf & {
+ /**
+ * Determines prominence
+ */
+ fontWeight?: 'normal' | 'bold';
+ /**
+ * Smaller buttons also remove extra shadow for less prominence
+ */
+ size?: EuiButtonProps['size'];
+ /**
+ * Determines if the button will have a down arrow or not
+ */
+ hasArrow?: boolean;
+ /**
+ * Adjusts the borders for groupings
+ */
+ groupPosition?: 'none' | 'left' | 'center' | 'right';
+ dataTestSubj?: string;
+};
+
+export const ToolbarButton: React.FunctionComponent = ({
+ children,
+ className,
+ fontWeight = 'normal',
+ size = 's',
+ hasArrow = true,
+ groupPosition = 'none',
+ dataTestSubj = '',
+ ...rest
+}) => {
+ const classes = classNames(
+ 'lnsToolbarButton',
+ groupPositionToClassMap[groupPosition],
+ [`lnsToolbarButton--${fontWeight}`, `lnsToolbarButton--${size}`],
+ className
+ );
+ return (
+
+ {children}
+
+ );
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.data.spec.hjson b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.data.spec.hjson
new file mode 100644
index 000000000..eb3c8a0ce
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.data.spec.hjson
@@ -0,0 +1,4 @@
+{
+ /* data configurations */
+ data: {}
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.layout.spec.hjson b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.layout.spec.hjson
new file mode 100644
index 000000000..f2bb3702d
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default.layout.spec.hjson
@@ -0,0 +1,11 @@
+{
+ /* layout configurations */
+ layout: {
+ /* configuration options can be found: https://plotly.com/javascript/reference/layout/ */
+ }
+
+ /* figure configurations */
+ config: {
+ /* configuration options can be found: https://plotly.com/javascript/configuration-options/ */
+ }
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default_spec.ts b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default_spec.ts
new file mode 100644
index 000000000..310f6613f
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/visualization_specs/default_spec.ts
@@ -0,0 +1,10 @@
+// @ts-ignore
+
+import hjson from 'hjson';
+import defaultLayoutSpec from '!!raw-loader!./default.layout.spec.hjson';
+import defaultDataSpec from '!!raw-loader!./default.data.spec.hjson';
+
+export const getDefaultSpec = (type = 'layout') => {
+ if (type === 'data') return defaultDataSpec;
+ return defaultLayoutSpec;
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.scss b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.scss
new file mode 100644
index 000000000..4c90496cd
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.scss
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.lnsChartSwitch__header {
+ > * {
+ display: flex;
+ align-items: center;
+ }
+}
+
+.lnsChartSwitch__summaryIcon {
+ margin-right: $euiSizeS;
+ transform: translateY(-1px);
+ color: $euiTextSubduedColor;
+}
+
+// Targeting img as this won't target normal EuiIcon's only the custom svgs's
+img.lnsChartSwitch__chartIcon { // sass-lint:disable-line no-qualifying-elements
+ // The large icons aren't square so max out the width to fill the height
+ width: 100%;
+}
+
+.lnsChartSwitch__search {
+ width: 4 * $euiSizeXXL;
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.tsx b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.tsx
new file mode 100644
index 000000000..4d96e88df
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/chart_switch.tsx
@@ -0,0 +1,114 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './chart_switch.scss';
+
+import React, { useState } from 'react';
+import { i18n } from '@osd/i18n';
+import {
+ EuiPopover,
+ EuiPopoverTitle,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiKeyPadMenu,
+ EuiKeyPadMenuItem,
+ EuiIcon,
+} from '@elastic/eui';
+import { ToolbarButton } from '../shared_components/toolbar_button';
+import { getPlotlyCategory } from '../../../visualizations/charts/shared/shared_configs';
+
+function VisualizationSummary(vis: any) {
+ return (
+ <>
+
+ {vis.label}
+ >
+ );
+}
+
+const VIS_CATEGORY = getPlotlyCategory('list');
+
+export const ChartSwitch = ({ setVis, vis, visualizationTypes }: any) => {
+ const [flyoutOpen, setFlyoutOpen] = useState(false);
+
+ const popoverWrappedSwitch = (
+ setFlyoutOpen(!flyoutOpen)}
+ data-test-subj="lnsChartSwitchPopover"
+ fontWeight="bold"
+ >
+
+
+ }
+ isOpen={flyoutOpen}
+ closePopover={() => setFlyoutOpen(false)}
+ anchorPosition="downLeft"
+ >
+ {VIS_CATEGORY.map((vis_category) => {
+ return (
+ <>
+
+
+
+ {i18n.translate('xpack.lens.configPanel.chartType', {
+ defaultMessage: `${vis_category}`,
+ })}
+
+
+
+
+ {visualizationTypes
+ .filter((v) => vis_category === v.category)
+ .map((v) => (
+ {v.label}}
+ title={v.fullLabel}
+ role="menuitem"
+ data-test-subj={`lnsChartSwitchPopover_${v.id}`}
+ onClick={() => {
+ setVis(v.id);
+ setFlyoutOpen(false);
+ }}
+ betaBadgeLabel={
+ v.selection.dataLoss !== 'nothing'
+ ? i18n.translate('xpack.lens.chartSwitch.dataLossLabel', {
+ defaultMessage: 'Data loss',
+ })
+ : undefined
+ }
+ betaBadgeTooltipContent={
+ v.selection.dataLoss !== 'nothing'
+ ? i18n.translate('xpack.lens.chartSwitch.dataLossDescription', {
+ defaultMessage:
+ 'Switching to this chart will lose some of the configuration',
+ })
+ : undefined
+ }
+ betaBadgeIconType={v.selection.dataLoss !== 'nothing' ? 'alert' : undefined}
+ >
+
+
+ ))}
+
+ >
+ );
+ })}
+
+ );
+
+ return {popoverWrappedSwitch}
;
+};
diff --git a/dashboards-observability/public/components/explorer/visualizations/workspace_panel/index.ts b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/index.ts
new file mode 100644
index 000000000..f8ed02d09
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { WorkspacePanel } from './workspace_panel';
diff --git a/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.scss b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.scss
new file mode 100644
index 000000000..36f5d15c2
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.scss
@@ -0,0 +1,9 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+.ws__header-dark {
+ background-color: transparent;
+}
\ No newline at end of file
diff --git a/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.tsx b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.tsx
new file mode 100644
index 000000000..9934e4f27
--- /dev/null
+++ b/dashboards-observability/public/components/explorer/visualizations/workspace_panel/workspace_panel.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import './workspace_panel.scss';
+
+import React, { useState, useMemo } from 'react';
+import { isEmpty } from 'lodash';
+import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiSwitch, EuiSpacer } from '@elastic/eui';
+import { Visualization } from '../../../visualizations/visualization';
+import { DataTable } from '../../../visualizations/charts/data_table/data_table';
+import { uiSettingsService } from '../../../../../common/utils';
+
+interface IWorkSpacePanel {
+ curVisId: string;
+ setCurVisId: any;
+ visualizations: any;
+}
+
+export function WorkspacePanel({ visualizations }: IWorkSpacePanel) {
+ const [isTableViewOn, setIsTableViewOn] = useState(false);
+ const VisualizationPanel = useMemo(() => {
+ return ;
+ }, [visualizations]);
+
+ return (
+ <>
+
+
+
+
+
+
+ {
+ setIsTableViewOn((staleState) => !staleState);
+ }}
+ aria-describedby="table view switcher"
+ compressed
+ />
+
+
+
+
+
+
+
+ {isTableViewOn ? : VisualizationPanel}
+
+
+
+ >
+ );
+}
diff --git a/dashboards-observability/public/components/index.tsx b/dashboards-observability/public/components/index.tsx
new file mode 100644
index 000000000..267cb6b5d
--- /dev/null
+++ b/dashboards-observability/public/components/index.tsx
@@ -0,0 +1,34 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { AppMountParameters, CoreStart } from '../../../../src/core/public';
+import { AppPluginStartDependencies } from '../types';
+import { App } from './app';
+
+export const Observability = (
+ CoreStartProp: CoreStart,
+ DepsStart: AppPluginStartDependencies,
+ AppMountParametersProp: AppMountParameters,
+ pplService: any,
+ dslService: any,
+ savedObjects: any,
+ timestampUtils: any
+) => {
+ ReactDOM.render(
+ ,
+ AppMountParametersProp.element
+ );
+
+ return () => ReactDOM.unmountComponentAtNode(AppMountParametersProp.element);
+};
diff --git a/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap
new file mode 100644
index 000000000..10647b786
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap
@@ -0,0 +1,1139 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rows per page
+ :
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` spec renders the empty component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+ No notebooks
+
+
+
+
+ Use notebooks to create post-mortem reports, build live infrastructure
+
+ reports, or foster explorative collaborations with data.
+
+
+
+
+
+
+
+
+
+
+ Create notebook
+
+
+
+
+
+
+
+
+ Add samples
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/notebook.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/notebook.test.tsx.snap
new file mode 100644
index 000000000..d184baf15
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/__tests__/__snapshots__/notebook.test.tsx.snap
@@ -0,0 +1,611 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Paragraph actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Notebook actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+ No paragraphs
+
+
+ Add a paragraph to compose your document or story. Notebooks now support two types of input:
+
+
+
+
+
+
+
+
+
+
+
+ Code block
+
+
+
+ Write contents directly using markdown, SQL or PPL.
+
+
+
+
+
+
+
+
+
+
+
+ Visualization
+
+
+
+ Import OpenSearch Dashboards or Observability visualizations to the notes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` spec renders the component 2`] = `null`;
+
+exports[` spec renders the empty component 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Paragraph actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Notebook actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Created
+
+
+ Invalid date
+
+
+
+
+
+
+
+
+
+
+
+ No paragraphs
+
+
+ Add a paragraph to compose your document or story. Notebooks now support two types of input:
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Code block
+
+
+
+ Write contents directly using markdown, SQL or PPL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Visualization
+
+
+
+ Import OpenSearch Dashboards or Observability visualizations to the notes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/__tests__/note_table.test.tsx b/dashboards-observability/public/components/notebooks/components/__tests__/note_table.test.tsx
new file mode 100644
index 000000000..70eb5fe30
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/__tests__/note_table.test.tsx
@@ -0,0 +1,84 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { NoteTable } from '../note_table';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the empty component', () => {
+ const fetchNotebooks = jest.fn();
+ const addSampleNotebooks = jest.fn();
+ const createNotebook = jest.fn();
+ const renameNotebook = jest.fn();
+ const cloneNotebook = jest.fn();
+ const deleteNotebook = jest.fn();
+ const setBreadcrumbs = jest.fn();
+ const setToast = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('renders the component', () => {
+ const fetchNotebooks = jest.fn();
+ const addSampleNotebooks = jest.fn();
+ const createNotebook = jest.fn();
+ const renameNotebook = jest.fn();
+ const cloneNotebook = jest.fn();
+ const deleteNotebook = jest.fn();
+ const setBreadcrumbs = jest.fn();
+ const setToast = jest.fn();
+ const notebooks = Array.from({ length: 5 }, (v, k) => ({
+ path: `path-${k}`,
+ id: `id-${k}`,
+ dateCreated: 'date-created',
+ dateModified: 'date-modified',
+ }));
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+
+ utils.getByText('Actions').click();
+ utils.getByText('Add samples').click();
+ utils.getAllByLabelText('Select this row')[0].click();
+ utils.getByText('Actions').click();
+ utils.getByText('Delete').click();
+ utils.getByText('Cancel').click();
+ utils.getAllByLabelText('Select this row')[0].click();
+ utils.getByText('Actions').click();
+ utils.getByText('Rename').click();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/__tests__/notebook.test.tsx b/dashboards-observability/public/components/notebooks/components/__tests__/notebook.test.tsx
new file mode 100644
index 000000000..eaabb3654
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/__tests__/notebook.test.tsx
@@ -0,0 +1,120 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render, waitFor } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import PPLService from '../../../../services/requests/ppl';
+import React from 'react';
+import { HttpResponse } from '../../../../../../../src/core/public';
+import httpClientMock from '../../../../../test/__mocks__/httpClientMock';
+import { sampleNotebook1 } from '../helpers/__tests__/sampleDefaultNotebooks';
+import { Notebook } from '../notebook';
+
+jest.mock('../../../../../../../src/plugins/embeddable/public', () => ({
+ ViewMode: {
+ EDIT: 'edit',
+ VIEW: 'view',
+ },
+}));
+
+// @ts-ignore
+global.fetch = jest.fn(() =>
+ Promise.resolve({
+ json: () =>
+ Promise.resolve({
+ status: {
+ statuses: [{ id: 'plugin:reportsDashboards' }],
+ },
+ }),
+ })
+);
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the empty component', async () => {
+ const pplService = new PPLService(httpClientMock);
+ const setBreadcrumbs = jest.fn();
+ const renameNotebook = jest.fn();
+ const cloneNotebook = jest.fn();
+ const deleteNotebook = jest.fn();
+ const setToast = jest.fn();
+ const location = jest.fn();
+ const history = jest.fn() as any;
+ history.replace = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ utils.getByText('Add code block').click();
+ utils.getByText('Add visualization').click();
+ });
+
+ it('renders the component', async () => {
+ const pplService = new PPLService(httpClientMock);
+ const setBreadcrumbs = jest.fn();
+ const renameNotebook = jest.fn();
+ const cloneNotebook = jest.fn();
+ const deleteNotebook = jest.fn();
+ const setToast = jest.fn();
+ const location = jest.fn();
+ const history = jest.fn() as any;
+ history.replace = jest.fn();
+ httpClientMock.get = jest.fn(() =>
+ Promise.resolve(({
+ ...sampleNotebook1,
+ path: sampleNotebook1.name,
+ visualizations: [
+ {
+ id: 'oiuccXwBYVazWqOO1e06',
+ name: 'Flight Count by Origin',
+ query:
+ 'source=opensearch_dashboards_sample_data_flights | fields Carrier,FlightDelayMin | stats sum(FlightDelayMin) as delays by Carrier',
+ type: 'bar',
+ timeField: 'timestamp',
+ },
+ ],
+ savedVisualizations: Array.from({ length: 5 }, (v, k) => ({
+ label: `vis-${k}`,
+ key: `vis-${k}`,
+ })),
+ } as unknown) as HttpResponse)
+ );
+ const utils = render(
+
+ );
+
+ await waitFor(() => {
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/__snapshots__/modal_containers.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/__snapshots__/modal_containers.test.tsx.snap
new file mode 100644
index 000000000..5ed44ca00
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/__snapshots__/modal_containers.test.tsx.snap
@@ -0,0 +1,118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`modal_containers spec render delete notebooks modal 1`] = `
+
+
+
+
+ title
+
+
+
+
+ message
+
+
+ The action cannot be undone.
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+ Delete
+
+
+
+
+`;
+
+exports[`modal_containers spec render get clone modal 1`] = `""`;
+
+exports[`modal_containers spec render get custom modal 1`] = `
+
+
+
+
+ title
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+ Confirm
+
+
+
+
+`;
+
+exports[`modal_containers spec render get delete modal 1`] = `""`;
+
+exports[`modal_containers spec render get delete modal 2`] = `""`;
+
+exports[`modal_containers spec render get sample notebooks modal 1`] = `""`;
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/default_parser.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/default_parser.test.tsx
new file mode 100644
index 000000000..3c03a3d5b
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/default_parser.test.tsx
@@ -0,0 +1,97 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { defaultParagraphParser } from '../default_parser';
+import {
+ sampleNotebook1,
+ sampleNotebook2,
+ sampleNotebook3,
+ sampleNotebook4,
+ sampleNotebook5,
+ sampleParsedParagraghs1,
+ sampleParsedParagraghs2,
+} from './sampleDefaultNotebooks';
+
+// Perfect schema
+describe('Testing default backend parser function with perfect schema', () => {
+ test('defaultParagraphParserTest1', (done) => {
+ const parsedParagraphs1 = defaultParagraphParser(sampleNotebook1.paragraphs);
+ const parsedParagraphs2 = defaultParagraphParser(sampleNotebook2.paragraphs);
+ const parsedParagraphs3 = defaultParagraphParser([]);
+ expect(parsedParagraphs1).toEqual(sampleParsedParagraghs1);
+ expect(parsedParagraphs2).toEqual(sampleParsedParagraghs2);
+ expect(parsedParagraphs3).toEqual([]);
+ done();
+ });
+
+ it('returns parsed paragraphs', () => {
+ const MockVis = sampleNotebook1.paragraphs[2].input.inputText;
+
+ const parsedPara = defaultParagraphParser(
+ Array.from({ length: 5 }, (v, k) => {
+ const isVisualization = k % 2 === 0;
+ return {
+ id: `paragraph-${k}`,
+ input: {
+ inputText: isVisualization ? MockVis : `text-${k}`,
+ inputType: isVisualization ? 'VISUALIZATION' : 'MARKDOWN',
+ },
+ output: [
+ {
+ result: isVisualization ? '' : `text-${k}`,
+ outputType: isVisualization ? 'VISUALIZATION' : 'MARKDOWN',
+ execution_time: '0s',
+ },
+ ],
+ };
+ })
+ );
+
+ const expected = Array.from({ length: 5 }, (v, k) => {
+ const isVisualization = k % 2 === 0;
+ return {
+ uniqueId: `paragraph-${k}`,
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: isVisualization,
+ vizObjectInput: isVisualization ? MockVis : '',
+ id: k + 1,
+ inp: isVisualization ? MockVis : `text-${k}`,
+ lang: isVisualization ? 'text/x-' : 'text/x-md',
+ editorLanguage: isVisualization ? '' : 'md',
+ typeOut: isVisualization ? ['VISUALIZATION'] : ['MARKDOWN'],
+ out: isVisualization ? [''] : [`text-${k}`],
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraRef: undefined,
+ paraDivRef: undefined,
+ visStartTime: isVisualization ? '2020-07-21T18:37:44.710Z' : undefined,
+ visEndTime: isVisualization ? '2020-08-20T18:37:44.710Z' : undefined,
+ visSavedObjId: isVisualization ? '935afa20-e0cd-11e7-9d07-1398ccfcefa3' : undefined,
+ };
+ });
+ expect(parsedPara).toEqual(expected);
+ });
+});
+
+// Issue in schema
+describe('Testing default backend parser function with wrong schema', () => {
+ test('defaultParagraphParserTest2', (done) => {
+ expect(() => {
+ const parsedParagraphs1 = defaultParagraphParser(sampleNotebook3.paragraphs);
+ }).toThrow(Error);
+ expect(() => {
+ const parsedParagraphs2 = defaultParagraphParser(sampleNotebook4.paragraphs);
+ }).toThrow(Error);
+ expect(() => {
+ const parsedParagraphs3 = defaultParagraphParser(sampleNotebook5.paragraphs);
+ }).toThrow(Error);
+ done();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/legacy_route_helpers.test.ts b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/legacy_route_helpers.test.ts
new file mode 100644
index 000000000..c4d1a7855
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/legacy_route_helpers.test.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { RedirectProps } from 'react-router-dom';
+import { convertLegacyNotebooksUrl } from '../legacy_route_helpers';
+
+describe('Test legacy route helpers', () => {
+ it('converts legacy notebooks url', () => {
+ const locations = [
+ {
+ pathname: '/app/notebooks-dashboards',
+ search: '',
+ hash: '#/GQ5icXwBJCegTOBKO4Um',
+ },
+ {
+ pathname: '/app/notebooks-dashboards',
+ search: '?view=view_both',
+ hash: '#/clPiPXwBEM7l9gC0xTpA',
+ },
+ {
+ pathname: '/testBasePath/app/notebooks-dashboards',
+ search: '?view=output_only&security_tenant=global',
+ hash: `#/GQ5icXwBJCegTOBKO4Um?_g=(time:(from:'2021-10-15T20:25:09.556Z',to:'2021-10-15T20:55:09.556Z'))`,
+ },
+ ] as Location[];
+ const expected = [
+ '/app/observability-dashboards#/notebooks/GQ5icXwBJCegTOBKO4Um',
+ '/app/observability-dashboards#/notebooks/clPiPXwBEM7l9gC0xTpA?view=view_both',
+ `/testBasePath/app/observability-dashboards#/notebooks/GQ5icXwBJCegTOBKO4Um?_g=(time:(from:'2021-10-15T20:25:09.556Z',to:'2021-10-15T20:55:09.556Z'))&view=output_only&security_tenant=global`,
+ ] as RedirectProps['to'][];
+ expect(locations.map((location) => convertLegacyNotebooksUrl(location))).toEqual(expected);
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/modal_containers.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/modal_containers.test.tsx
new file mode 100644
index 000000000..c0c982a9b
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/modal_containers.test.tsx
@@ -0,0 +1,98 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import {
+ DeleteNotebookModal,
+ getCloneModal,
+ getCustomModal,
+ getDeleteModal,
+ getSampleNotebooksModal,
+} from '../modal_containers';
+
+describe('modal_containers spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('render get custom modal', () => {
+ const runModal = jest.fn();
+ const closeModal = jest.fn();
+ const wrapper = shallow(
+ getCustomModal(
+ runModal,
+ closeModal,
+ 'label',
+ 'title',
+ 'Cancel',
+ 'Confirm',
+ 'mock-path',
+ 'help text'
+ )
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('render get clone modal', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const wrapper = shallow(getCloneModal(onCancel, onConfirm));
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('render get sample notebooks modal', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const wrapper = shallow(getSampleNotebooksModal(onCancel, onConfirm));
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('render get delete modal', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const wrapper = shallow(
+ getDeleteModal(onCancel, onConfirm, 'Delete', 'Delete message', 'Confirm message')
+ );
+ expect(wrapper).toMatchSnapshot();
+
+ const noConfirmMessageWrapper = shallow(
+ getDeleteModal(onCancel, onConfirm, 'Delete', 'Delete message')
+ );
+ expect(noConfirmMessageWrapper).toMatchSnapshot();
+ });
+
+ it('render delete notebooks modal', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const wrapper = shallow(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('checks delete notebooks modal', () => {
+ const onCancel = jest.fn();
+ const onConfirm = jest.fn();
+ const utils = render(
+
+ );
+ fireEvent.change(utils.getAllByTestId('delete-notebook-modal-input')[0], {
+ target: { value: 'delete' },
+ });
+ fireEvent.click(utils.getAllByTestId('delete-notebook-modal-delete-button')[0]);
+ expect(onConfirm).toBeCalled();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/reporting_context_menu_helper.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/reporting_context_menu_helper.test.tsx
new file mode 100644
index 000000000..90b951df2
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/reporting_context_menu_helper.test.tsx
@@ -0,0 +1,139 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ contextMenuCreateReportDefinition,
+ contextMenuViewReports,
+ generateInContextReport
+} from '../reporting_context_menu_helper';
+
+describe('reporting_context_menu_helper tests', () => {
+ test('contextMenuViewReports will redirect', () => {
+ const savedLocation = window.location;
+ // @ts-ignore
+ delete window.location;
+
+ window.location = {
+ ...savedLocation,
+ assign: jest.fn(),
+ };
+ contextMenuViewReports();
+ expect(window.location.assign).toBeCalledWith('reports-dashboards#/');
+ window.location = savedLocation;
+ });
+
+ test('contextMenuCreateReportDefinition', () => {
+ const savedLocation = window.location;
+ // @ts-ignore
+ delete window.location;
+
+ window.location = {
+ ...savedLocation,
+ assign: jest.fn(),
+ };
+ contextMenuCreateReportDefinition('https://mock-base.uri/mock-base-path');
+ expect(window.location.assign).toBeCalledWith(
+ 'reports-dashboards#/create?previous=notebook:mock-base-path?timeFrom=0?timeTo=0'
+ );
+ window.location = savedLocation;
+ });
+
+ function generateReport(
+ status: number,
+ filename: string,
+ tenant: string,
+ setToast: (...args: any[]) => void,
+ toggleReportingLoadingModal: (toggle: boolean) => void
+ ) {
+ const fileFormat = filename.match(/\.([^.]+)$/)?.[1] || 'pdf';
+ // @ts-ignore
+ global.fetch = jest.fn(() =>
+ Promise.resolve({
+ status,
+ json: () => Promise.resolve({ filename, fileFormat, data: 'test-data' }),
+ text: () => Promise.resolve({ tenant }),
+ })
+ );
+ const props = { setToast };
+ return generateInContextReport(fileFormat, props, toggleReportingLoadingModal);
+ }
+
+ it('generates csv for private tenant', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(200, 'test.csv', '__user__', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith('Successfully generated report.', 'success');
+ });
+
+ it('generates pdf for global tenant', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(200, 'test.pdf', '', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith('Successfully generated report.', 'success');
+ });
+
+ it('generates png for custom tenant', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(200, 'test.png', 'custom_tenant', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith('Successfully generated report.', 'success');
+ });
+
+ it('generates png for custom tenant', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(200, 'test.png', 'custom_tenant', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith('Successfully generated report.', 'success');
+ });
+
+ it('handles 404 error', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(404, 'test.png', 'custom_tenant', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith(
+ 'Download error',
+ 'danger',
+ 'There was an error generating this report.'
+ );
+ });
+
+ it('handles permission error', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(403, 'test.png', 'custom_tenant', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith(
+ 'Error generating report,',
+ 'danger',
+ 'Insufficient permissions. Reach out to your OpenSearch Dashboards administrator.'
+ );
+ });
+
+ it('handles timeout error', async () => {
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateReport(503, 'test.png', 'custom_tenant', setToast, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith(
+ 'Error generating report.',
+ 'danger',
+ 'Timed out generating on-demand report from notebook. Try again later.'
+ );
+ });
+
+ it('handles tenant errors', async () => {
+ global.fetch = jest.fn(() => Promise.reject({ status: 500 }));
+ const setToast = jest.fn();
+ const toggleReportingLoadingModal = jest.fn();
+ await generateInContextReport('csv', { setToast }, toggleReportingLoadingModal);
+ expect(toggleReportingLoadingModal).toBeCalledWith(true);
+ expect(setToast).toBeCalledWith('Tenant error', 'danger', 'Failed to get user tenant.');
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleDefaultNotebooks.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleDefaultNotebooks.tsx
new file mode 100644
index 000000000..17e077ed5
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleDefaultNotebooks.tsx
@@ -0,0 +1,354 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// Sample notebook with all input and output
+export const sampleNotebook1 = {
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ output: [{ result: '# Type your input here', outputType: 'MARKDOWN', execution_time: '0s' }],
+ input: { inputText: '# Type your input here', inputType: 'MARKDOWN' },
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T18:00:59.845Z',
+ id: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ },
+ {
+ output: [{ result: '# add code here\n', outputType: 'MARKDOWN', execution_time: '0s' }],
+ input: { inputText: '# add code here\n', inputType: 'MARKDOWN' },
+ dateCreated: '2020-08-20T18:01:07.662Z',
+ dateModified: '2020-08-20T18:01:18.295Z',
+ id: 'paragraph_c3107b15-da7d-4836-aef4-0996abbc8ab2',
+ },
+ {
+ output: [{ result: '', outputType: 'VISUALIZATION', execution_time: '0s' }],
+ input: {
+ inputText:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ inputType: 'VISUALIZATION',
+ },
+ dateCreated: '2020-08-20T18:37:44.809Z',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ id: 'paragraph_6d3237a9-6486-4f93-aa25-0a1c838faabd',
+ },
+ {
+ output: [
+ {
+ result:
+ '{"schema":[{"name":"FlightNum","type":"keyword"},{"name":"Origin","type":"keyword"},{"name":"OriginLocation","type":"geo_point"},{"name":"DestLocation","type":"geo_point"},{"name":"FlightDelay","type":"boolean"},{"name":"DistanceMiles","type":"float"},{"name":"FlightTimeMin","type":"float"},{"name":"OriginWeather","type":"keyword"},{"name":"dayOfWeek","type":"integer"},{"name":"AvgTicketPrice","type":"float"},{"name":"Carrier","type":"keyword"},{"name":"FlightDelayMin","type":"integer"},{"name":"OriginRegion","type":"keyword"},{"name":"DestAirportID","type":"keyword"},{"name":"FlightDelayType","type":"keyword"},{"name":"timestamp","type":"timestamp"},{"name":"Dest","type":"keyword"},{"name":"FlightTimeHour","type":"keyword"},{"name":"Cancelled","type":"boolean"},{"name":"DistanceKilometers","type":"float"},{"name":"OriginCityName","type":"keyword"},{"name":"DestWeather","type":"keyword"},{"name":"OriginCountry","type":"keyword"},{"name":"DestCountry","type":"keyword"},{"name":"DestRegion","type":"keyword"},{"name":"DestCityName","type":"keyword"},{"name":"OriginAirportID","type":"keyword"}],"datarows":[["9HY9SWR","Frankfurt am Main Airport",{"lat":50.033333,"lon":8.570556},{"lat":-33.94609833,"lon":151.177002},false,10247.856,1030.7704,"Sunny",0,841.2656,"OpenSearch Dashboards Airlines",0,"DE-HE","SYD","No Delay","2021-11-01 00:00:00","Sydney Kingsford Smith International Airport","17.179506930998397",false,16492.326,"Frankfurt am Main","Rain","DE","AU","SE-BD","Sydney","FRA"],["X98CCZO","Cape Town International Airport",{"lat":-33.96480179,"lon":18.60169983},{"lat":45.505299,"lon":12.3519},false,5482.6064,464.3895,"Clear",0,882.98267,"Logstash Airways",0,"SE-BD","VE05","No Delay","2021-11-01 18:27:00","Venice Marco Polo Airport","7.73982468459836",false,8823.4,"Cape Town","Sunny","ZA","IT","IT-34","Venice","CPT"]],"total":2,"size":2,"status":200}',
+ outputType: 'QUERY',
+ execution_time: '0s',
+ },
+ ],
+ input: {
+ inputText: '%sql select * from opensearch_dashboards_sample_data_flights limit 2',
+ inputType: 'QUERY',
+ },
+ dateCreated: '2020-08-20T18:37:44.809Z',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ id: 'paragraph_f1b2db55-8704-4822-a8ff-6445fe1fa10c',
+ },
+ ],
+};
+
+// Parsed Output of sample notebook1
+export const sampleParsedParagraghs1 = [
+ {
+ uniqueId: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 1,
+ inp: '# Type your input here',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: undefined,
+ visSavedObjId: undefined,
+ visStartTime: undefined,
+ lang: 'text/x-md',
+ editorLanguage: 'md',
+ typeOut: ['MARKDOWN'],
+ out: ['# Type your input here'],
+ },
+ {
+ uniqueId: 'paragraph_c3107b15-da7d-4836-aef4-0996abbc8ab2',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 2,
+ inp: '# add code here\n',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: undefined,
+ visSavedObjId: undefined,
+ visStartTime: undefined,
+ lang: 'text/x-md',
+ editorLanguage: 'md',
+ typeOut: ['MARKDOWN'],
+ out: ['# add code here\n'],
+ },
+ {
+ uniqueId: 'paragraph_6d3237a9-6486-4f93-aa25-0a1c838faabd',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: true,
+ vizObjectInput:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ id: 3,
+ inp: '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ lang: 'text/x-',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: '2020-08-20T18:37:44.710Z',
+ visSavedObjId: '935afa20-e0cd-11e7-9d07-1398ccfcefa3',
+ visStartTime: '2020-07-21T18:37:44.710Z',
+ editorLanguage: '',
+ typeOut: ['VISUALIZATION'],
+ out: [''],
+ },
+ {
+ uniqueId: 'paragraph_f1b2db55-8704-4822-a8ff-6445fe1fa10c',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 4,
+ inp: `%sql select * from opensearch_dashboards_sample_data_flights limit 2`,
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: undefined,
+ visSavedObjId: undefined,
+ visStartTime: undefined,
+ lang: 'text/x-',
+ editorLanguage: '',
+ typeOut: ['QUERY'],
+ out: [
+ '{"schema":[{"name":"FlightNum","type":"keyword"},{"name":"Origin","type":"keyword"},{"name":"OriginLocation","type":"geo_point"},{"name":"DestLocation","type":"geo_point"},{"name":"FlightDelay","type":"boolean"},{"name":"DistanceMiles","type":"float"},{"name":"FlightTimeMin","type":"float"},{"name":"OriginWeather","type":"keyword"},{"name":"dayOfWeek","type":"integer"},{"name":"AvgTicketPrice","type":"float"},{"name":"Carrier","type":"keyword"},{"name":"FlightDelayMin","type":"integer"},{"name":"OriginRegion","type":"keyword"},{"name":"DestAirportID","type":"keyword"},{"name":"FlightDelayType","type":"keyword"},{"name":"timestamp","type":"timestamp"},{"name":"Dest","type":"keyword"},{"name":"FlightTimeHour","type":"keyword"},{"name":"Cancelled","type":"boolean"},{"name":"DistanceKilometers","type":"float"},{"name":"OriginCityName","type":"keyword"},{"name":"DestWeather","type":"keyword"},{"name":"OriginCountry","type":"keyword"},{"name":"DestCountry","type":"keyword"},{"name":"DestRegion","type":"keyword"},{"name":"DestCityName","type":"keyword"},{"name":"OriginAirportID","type":"keyword"}],"datarows":[["9HY9SWR","Frankfurt am Main Airport",{"lat":50.033333,"lon":8.570556},{"lat":-33.94609833,"lon":151.177002},false,10247.856,1030.7704,"Sunny",0,841.2656,"OpenSearch Dashboards Airlines",0,"DE-HE","SYD","No Delay","2021-11-01 00:00:00","Sydney Kingsford Smith International Airport","17.179506930998397",false,16492.326,"Frankfurt am Main","Rain","DE","AU","SE-BD","Sydney","FRA"],["X98CCZO","Cape Town International Airport",{"lat":-33.96480179,"lon":18.60169983},{"lat":45.505299,"lon":12.3519},false,5482.6064,464.3895,"Clear",0,882.98267,"Logstash Airways",0,"SE-BD","VE05","No Delay","2021-11-01 18:27:00","Venice Marco Polo Airport","7.73982468459836",false,8823.4,"Cape Town","Sunny","ZA","IT","IT-34","Venice","CPT"]],"total":2,"size":2,"status":200}',
+ ],
+ },
+];
+
+// Sample notebook with all input and cleared outputs
+export const sampleNotebook2 = {
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ output: [
+ {
+ result:
+ '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ outputType: 'MARKDOWN',
+ execution_time: '0s',
+ },
+ ],
+ input: {
+ inputText:
+ '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ inputType: 'MARKDOWN',
+ },
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ id: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ },
+ {
+ output: [],
+ input: { inputText: '# no output here\n', inputType: 'MARKDOWN' },
+ dateCreated: '2020-08-20T18:01:07.662Z',
+ dateModified: '2020-08-20T19:09:19.210Z',
+ id: 'paragraph_c3107b15-da7d-4836-aef4-0996abbc8ab2',
+ },
+ {
+ output: [],
+ input: {
+ inputText:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ inputType: 'VISUALIZATION',
+ },
+ dateCreated: '2020-08-20T18:37:44.809Z',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ id: 'paragraph_6d3237a9-6486-4f93-aa25-0a1c838faabd',
+ },
+ ],
+};
+
+// Parsed Output of sample notebook2
+export const sampleParsedParagraghs2 = [
+ {
+ uniqueId: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 1,
+ inp: '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ lang: 'text/x-md',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: undefined,
+ visSavedObjId: undefined,
+ visStartTime: undefined,
+ editorLanguage: 'md',
+ typeOut: ['MARKDOWN'],
+ out: [
+ '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ ],
+ },
+ {
+ uniqueId: 'paragraph_c3107b15-da7d-4836-aef4-0996abbc8ab2',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 2,
+ inp: '# no output here\n',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: undefined,
+ visSavedObjId: undefined,
+ visStartTime: undefined,
+ lang: 'text/x-md',
+ editorLanguage: 'md',
+ typeOut: [],
+ out: [],
+ },
+ {
+ uniqueId: 'paragraph_6d3237a9-6486-4f93-aa25-0a1c838faabd',
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: true,
+ vizObjectInput:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ id: 3,
+ inp: '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ lang: 'text/x-',
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraDivRef: undefined,
+ paraRef: undefined,
+ visEndTime: '2020-08-20T18:37:44.710Z',
+ visSavedObjId: '935afa20-e0cd-11e7-9d07-1398ccfcefa3',
+ visStartTime: '2020-07-21T18:37:44.710Z',
+ editorLanguage: '',
+ typeOut: [],
+ out: [],
+ },
+];
+
+// Sample notebook with no input
+export const sampleNotebook3 = {
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ output: [
+ {
+ result:
+ '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ outputType: 'MARKDOWN',
+ execution_time: '0s',
+ },
+ ],
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ id: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ },
+ ],
+};
+
+// Sample notebook with no paragraph id
+export const sampleNotebook4 = {
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ output: [
+ {
+ result:
+ '# Type no output here\n* Sample link: [link](https://opensearch.org/)\n* ~~Strike~~, **Bold**, __Italic__',
+ outputType: 'MARKDOWN',
+ execution_time: '0s',
+ },
+ ],
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ },
+ ],
+};
+
+// Sample notebook with no input and output
+export const sampleNotebook5 = {
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T19:13:06.509Z',
+ id: 'paragraph_c3107b15-da7d-4836-aef4-0996abbc8ab2',
+ },
+ ],
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleZeppelinNotebooks.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleZeppelinNotebooks.tsx
new file mode 100644
index 000000000..db07da1c5
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/sampleZeppelinNotebooks.tsx
@@ -0,0 +1,359 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// Sample notebook with all input and output
+export const sampleNotebook1 = {
+ paragraphs: [
+ {
+ text:
+ "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to play around with notebooks and Paragraphs",
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ results: {
+ code: 'SUCCESS',
+ msg: [
+ {
+ type: 'HTML',
+ data:
+ '\n
Hi Everyone \n
\nHere’s a demo on OpenSearch Dashboards Notebooks \nYou may use the top left buttons to play around with notebooks and Paragraphs \n \n\n
',
+ },
+ ],
+ },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_901298942',
+ id: 'paragraph_1596519508360_932236116',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ {
+ title: 'VISUALIZATION',
+ text:
+ '%sh #vizobject:{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:25:28.588',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958728587_1310320520',
+ id: 'paragraph_1597958728587_1310320520',
+ dateCreated: '2020-08-20 21:25:28.587',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
+
+// Parsed Output of sample notebook1
+export const sampleParsedParagraghs1 = [
+ {
+ uniqueId: 'paragraph_1596519508360_932236116',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 1,
+ inp:
+ "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to play around with notebooks and Paragraphs",
+ lang: 'text/x-',
+ editorLanguage: '',
+ typeOut: ['HTML'],
+ out: [
+ '\n
Hi Everyone \n
\nHere’s a demo on OpenSearch Dashboards Notebooks \nYou may use the top left buttons to play around with notebooks and Paragraphs \n \n\n
',
+ ],
+ },
+ {
+ uniqueId: 'paragraph_1597958728587_1310320520',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: true,
+ vizObjectInput:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ id: 2,
+ inp:
+ '%sh #vizobject:{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ lang: 'text/x-',
+ editorLanguage: '',
+ typeOut: [],
+ out: [],
+ },
+];
+
+// Sample notebook with all input and cleared outputs
+export const sampleNotebook2 = {
+ paragraphs: [
+ {
+ text:
+ "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to play around with notebooks and Paragraphs",
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_901298942',
+ id: 'paragraph_1596519508360_932236116',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ {
+ title: 'Paragraph inserted',
+ text: '%md\n\n## Greetings!\n* Yay! you may import and export me ',
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_1715920734',
+ id: 'paragraph_1596742076640_674206137',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ {
+ title: 'Paragraph inserted',
+ text:
+ "%md\n\n### Let's use Visualization API with dashboard container to embed Visualizations in notebooks\n2. **Unpin** the container to *edit the size* or *delete it*\n3. **Refresh** the container after *date is changed*",
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_931410594',
+ id: 'paragraph_1596524302932_2112910756',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ {
+ title: 'VISUALIZATION',
+ text:
+ '%sh #vizobject:{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:25:28.588',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958728587_1310320520',
+ id: 'paragraph_1597958728587_1310320520',
+ dateCreated: '2020-08-20 21:25:28.587',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
+
+// Parsed Output of sample notebook2
+export const sampleParsedParagraghs2 = [
+ {
+ uniqueId: 'paragraph_1596519508360_932236116',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 1,
+ inp:
+ "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to play around with notebooks and Paragraphs",
+ lang: 'text/x-',
+ editorLanguage: '',
+ typeOut: [],
+ out: [],
+ },
+ {
+ uniqueId: 'paragraph_1596742076640_674206137',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 2,
+ inp: '%md\n\n## Greetings!\n* Yay! you may import and export me ',
+ lang: 'text/x-md',
+ editorLanguage: 'md',
+ typeOut: [],
+ out: [],
+ },
+ {
+ uniqueId: 'paragraph_1596524302932_2112910756',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: false,
+ vizObjectInput: '',
+ id: 3,
+ inp:
+ "%md\n\n### Let's use Visualization API with dashboard container to embed Visualizations in notebooks\n2. **Unpin** the container to *edit the size* or *delete it*\n3. **Refresh** the container after *date is changed*",
+ lang: 'text/x-md',
+ editorLanguage: 'md',
+ typeOut: [],
+ out: [],
+ },
+ {
+ uniqueId: 'paragraph_1597958728587_1310320520',
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: true,
+ vizObjectInput:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ id: 4,
+ inp:
+ '%sh #vizobject:{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ lang: 'text/x-',
+ editorLanguage: '',
+ typeOut: [],
+ out: [],
+ },
+];
+
+// Sample notebook with no paragraph Id
+export const sampleNotebook3 = {
+ paragraphs: [
+ {
+ text:
+ "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to play around with notebooks and Paragraphs",
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ results: {
+ code: 'SUCCESS',
+ msg: [
+ {
+ type: 'HTML',
+ data:
+ '\n
Hi Everyone \n
\nHere’s a demo on OpenSearch Dashboards Notebooks \nYou may use the top left buttons to play around with notebooks and Paragraphs \n \n\n
',
+ },
+ ],
+ },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_901298942',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
+
+// Sample notebook with no VISUALIZAITON title
+export const sampleNotebook4 = {
+ paragraphs: [
+ {
+ text:
+ '%sh #vizobject:{"viewMode":"view","panels":{"1":{"gridData":{"x":15,"y":0,"w":20,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"06cf9c40-9ee8-11e7-8711-e7a007dcef99"}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"iab4eaba1-e32b-11ea-aac8-99f209533253","timeRange":{"to":"2020-08-20T21:25:28.538Z","from":"2020-07-21T21:25:28.538Z"},"title":"embed_viz_iab4eaba1-e32b-11ea-aac8-99f209533253","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:25:28.588',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958728587_1310320520',
+ id: 'paragraph_1597958728587_1310320520',
+ dateCreated: '2020-08-20 21:25:28.587',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
+
+// Sample notebook with no input and output
+export const sampleNotebook5 = {
+ paragraphs: [
+ {
+ user: 'anonymous',
+ dateUpdated: '2020-08-20 21:25:28.588',
+ config: {},
+ settings: { params: {}, forms: {} },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958728587_1310320520',
+ id: 'paragraph_1597958728587_1310320520',
+ dateCreated: '2020-08-20 21:25:28.587',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/__tests__/zeppelin_parser.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/zeppelin_parser.test.tsx
new file mode 100644
index 000000000..df6542620
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/__tests__/zeppelin_parser.test.tsx
@@ -0,0 +1,44 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { zeppelinParagraphParser } from '../zeppelin_parser';
+import {
+ sampleNotebook1,
+ sampleNotebook2,
+ sampleNotebook3,
+ sampleNotebook4,
+ sampleNotebook5,
+ sampleParsedParagraghs1,
+ sampleParsedParagraghs2,
+} from './sampleZeppelinNotebooks';
+
+// Perfect schema
+describe('Testing Zeppelin backend parser function with perfect schema', () => {
+ test('zeppelinParagraphParserTest1', async (done) => {
+ const parsedParagraphs1 = zeppelinParagraphParser(sampleNotebook1.paragraphs);
+ const parsedParagraphs2 = zeppelinParagraphParser(sampleNotebook2.paragraphs);
+ const parsedParagraphs3 = zeppelinParagraphParser([]);
+ expect(parsedParagraphs1).toEqual(sampleParsedParagraghs1);
+ expect(parsedParagraphs2).toEqual(sampleParsedParagraghs2);
+ expect(parsedParagraphs3).toEqual([]);
+ done();
+ });
+});
+
+// Issue in schema
+describe('Testing default backend parser function with wrong schema', () => {
+ test('zeppelinParagraphParserTest2', async (done) => {
+ expect(() => {
+ const parsedParagraphs1 = zeppelinParagraphParser(sampleNotebook3.paragraphs);
+ }).toThrow(Error);
+ expect(() => {
+ const parsedParagraphs2 = zeppelinParagraphParser(sampleNotebook4.paragraphs);
+ }).toThrow(Error);
+ expect(() => {
+ const parsedParagraphs3 = zeppelinParagraphParser(sampleNotebook5.paragraphs);
+ }).toThrow(Error);
+ done();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/custom_input_modal.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/custom_input_modal.test.tsx.snap
new file mode 100644
index 000000000..69461a254
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/custom_input_modal.test.tsx.snap
@@ -0,0 +1,101 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
+
+
+
+
+ title
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+ Confirm
+
+
+
+
+`;
+
+exports[` spec renders the component 2`] = `
+
+
+
+
+ title
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+
+ Confirm
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/reporting_loading_modal.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/reporting_loading_modal.test.tsx.snap
new file mode 100644
index 000000000..08ff02523
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/__snapshots__/reporting_loading_modal.test.tsx.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
`;
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/custom_input_modal.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/custom_input_modal.test.tsx
new file mode 100644
index 000000000..452696ed8
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/custom_input_modal.test.tsx
@@ -0,0 +1,68 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { CustomInputModal } from '../custom_input_modal';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the component', () => {
+ const runModal = jest.fn();
+ const closeModal = jest.fn();
+ const wrapper = shallow(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+
+ const emptyNameWrapper = shallow(
+
+ );
+ expect(emptyNameWrapper).toMatchSnapshot();
+ });
+
+ it('clicks buttons', () => {
+ const runModal = jest.fn();
+ const closeModal = jest.fn();
+ const utils = render(
+
+ );
+ fireEvent.change(utils.getByTestId('custom-input-modal-input'), {
+ target: { value: 'test-name' },
+ });
+ utils.getByTestId('custom-input-modal-confirm-button').click();
+ expect(runModal).toBeCalledWith('test-name');
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/reporting_loading_modal.test.tsx b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/reporting_loading_modal.test.tsx
new file mode 100644
index 000000000..abfd4e5a0
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/__tests__/reporting_loading_modal.test.tsx
@@ -0,0 +1,22 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { GenerateReportLoadingModal } from '../reporting_loading_modal';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the component', () => {
+ const setShowLoading = jest.fn();
+ const utils = render( );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ utils.getByTestId('reporting-loading-modal-close-button').click();
+ expect(setShowLoading).toBeCalledWith(false);
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/custom_input_modal.tsx b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/custom_input_modal.tsx
new file mode 100644
index 000000000..5c1198649
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/custom_input_modal.tsx
@@ -0,0 +1,83 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import {
+ EuiButtonEmpty,
+ EuiForm,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiOverlayMask,
+ EuiFormRow,
+ EuiFieldText,
+ EuiButton,
+} from '@elastic/eui';
+
+/*
+ * "CustomInputModalProps" component is used to create a modal with an input filed
+ *
+ * Props taken in as params are:
+ * runModal - function to fetch input field value and trigger closing modal
+ * closeModal - function to trigger closing modal
+ * titletxt - string as header for title of modal
+ * labelTxt - string as header for input field
+ * btn1txt - string as content to fill "close button"
+ * btn2txt - string as content to fill "confirm button"
+ * openNoteName - Default input value for the field
+ */
+type CustomInputModalProps = {
+ runModal: (value: string) => void;
+ closeModal: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void;
+ labelTxt: string;
+ titletxt: string;
+ btn1txt: string;
+ btn2txt: string;
+ openNoteName: string;
+ helpText: string;
+};
+
+export const CustomInputModal = (props: CustomInputModalProps) => {
+ const { runModal, closeModal, labelTxt, titletxt, btn1txt, btn2txt, openNoteName, helpText } = props;
+ const [value, setValue] = useState(openNoteName || ''); // sets input value
+
+ const onChange = (e: React.ChangeEvent) => {
+ setValue(e.target.value);
+ };
+
+ return (
+
+
+
+ {titletxt}
+
+
+
+
+
+ onChange(e)}
+ />
+
+
+
+
+
+ {btn1txt}
+ runModal(value)} fill>
+ {btn2txt}
+
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/reporting_loading_modal.tsx b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/reporting_loading_modal.tsx
new file mode 100644
index 000000000..97de6788d
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/custom_modals/reporting_loading_modal.tsx
@@ -0,0 +1,70 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiOverlayMask,
+ EuiModal,
+ EuiModalHeader,
+ EuiTitle,
+ EuiText,
+ EuiModalBody,
+ EuiSpacer,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiLoadingSpinner,
+ EuiButton
+} from "@elastic/eui";
+import React from "react";
+
+export function GenerateReportLoadingModal(props: { setShowLoading: any; }) {
+ const {
+ setShowLoading
+ } = props;
+
+ const closeModal = () => {
+ setShowLoading(false);
+ };
+
+ return (
+
+
+
+
+
+
+ Generating report
+
+
+
+
+ Preparing your file for download.
+ You can close this dialog while we continue in the background.
+
+
+
+
+
+
+
+
+
+
+ Close
+
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/default_parser.tsx b/dashboards-observability/public/components/notebooks/components/helpers/default_parser.tsx
new file mode 100644
index 000000000..c38dad3cd
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/default_parser.tsx
@@ -0,0 +1,119 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { ParaType } from '../../../../../common/types/notebooks';
+
+// Get the type of output and result in a default notebook paragraph
+// Param: Default Backend Paragraph
+const parseOutput = (paraObject: any) => {
+ try {
+ let outputType = [];
+ let result = [];
+ paraObject.output.map((output: { outputType: string; result: string }) => {
+ outputType.push(output.outputType);
+ result.push(output.result);
+ });
+ return {
+ outputType: outputType,
+ outputData: result,
+ };
+ } catch (error) {
+ return {
+ outputType: [],
+ outputData: [],
+ };
+ }
+};
+
+// Get the coding language by type of paragraph
+// Param: Default Backend Paragraph
+const parseInputType = (paraObject: any) => {
+ try {
+ if (paraObject.input.inputType === 'MARKDOWN') {
+ return 'md';
+ } else {
+ return '';
+ }
+ } catch (error) {
+ throw new Error('Parsing Input Issue ' + error);
+ }
+};
+
+// Get the visualization by type of paragraph
+// Param: Default Backend Paragraph
+const parseVisualization = (paraObject: any) => {
+ try {
+ if (paraObject.input.inputType.includes('VISUALIZATION')) {
+ let vizContent = paraObject.input.inputText;
+ const startDate = new Date();
+ startDate.setDate(startDate.getDate() - 30);
+ let visStartTime = startDate.toISOString();
+ let visEndTime = new Date().toISOString();
+ let visSavedObjId = '';
+ if (vizContent !== '') {
+ const { panels, timeRange } = JSON.parse(vizContent);
+ visStartTime = timeRange.from;
+ visEndTime = timeRange.to;
+ visSavedObjId = panels['1'].explicitInput.savedObjectId;
+ }
+ return {
+ isViz: true,
+ VizObject: vizContent,
+ visStartTime,
+ visEndTime,
+ visSavedObjId,
+ };
+ } else {
+ return {
+ isViz: false,
+ VizObject: '',
+ };
+ }
+ } catch (error) {
+ throw new Error('Parsing Input Issue ' + error);
+ }
+};
+
+// Placeholder for default parser
+// Param: Default Backend Paragraph
+export const defaultParagraphParser = (defaultBackendParagraphs: any) => {
+ let parsedPara: Array = [];
+ try {
+ defaultBackendParagraphs.map((paraObject: any, index: number) => {
+ const codeLanguage = parseInputType(paraObject);
+ const vizParams = parseVisualization(paraObject);
+ const message = parseOutput(paraObject);
+
+ let tempPara: ParaType = {
+ uniqueId: paraObject.id,
+ isRunning: false,
+ inQueue: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: vizParams.isViz,
+ vizObjectInput: vizParams.VizObject,
+ id: index + 1,
+ inp: paraObject.input.inputText || '',
+ lang: 'text/x-' + codeLanguage,
+ editorLanguage: codeLanguage,
+ typeOut: message.outputType,
+ out: message.outputData,
+ isInputExpanded: false,
+ isOutputStale: false,
+ paraRef: undefined,
+ paraDivRef: undefined,
+ visStartTime: vizParams.visStartTime,
+ visEndTime: vizParams.visEndTime,
+ visSavedObjId: vizParams.visSavedObjId,
+ };
+ parsedPara.push(tempPara);
+ });
+ return parsedPara;
+ } catch (error) {
+ throw new Error('Parsing Paragraph Issue ' + error);
+ }
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/download_json.tsx b/dashboards-observability/public/components/notebooks/components/helpers/download_json.tsx
new file mode 100644
index 000000000..53128ac35
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/download_json.tsx
@@ -0,0 +1,14 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// Helper function to create download object
+export function onDownload(content: any, fileName: string) {
+ let dataUri =
+ 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(content));
+ let downloadElement = document.createElement('a');
+ downloadElement.setAttribute('href', dataUri);
+ downloadElement.setAttribute('download', fileName);
+ downloadElement.click();
+}
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/legacy_route_helpers.ts b/dashboards-observability/public/components/notebooks/components/helpers/legacy_route_helpers.ts
new file mode 100644
index 000000000..8bda04cc5
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/legacy_route_helpers.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { observabilityID } from "../../../../../common/constants/shared";
+
+export const convertLegacyNotebooksUrl = (location: Location)=> {
+ const pathname = location.pathname.replace('notebooks-dashboards', observabilityID);
+ const hash = `#/notebooks${location.hash.replace(/^#/, '')}${
+ location.hash.includes('?') ? location.search.replace(/^\?/, '&') : location.search
+ }`;
+ return pathname + hash;
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/modal_containers.tsx b/dashboards-observability/public/components/notebooks/components/helpers/modal_containers.tsx
new file mode 100644
index 000000000..53448012d
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/modal_containers.tsx
@@ -0,0 +1,183 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useState } from 'react';
+import {
+ EuiOverlayMask,
+ EuiConfirmModal,
+ EuiButton,
+ EuiButtonEmpty,
+ EuiFieldText,
+ EuiForm,
+ EuiFormRow,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiText,
+ EuiSpacer
+} from '@elastic/eui';
+import { CustomInputModal } from './custom_modals/custom_input_modal';
+
+/* The file contains helper functions for modal layouts
+ * getCustomModal - returns modal with input field
+ * getCloneModal - returns a confirm-modal with clone option
+ * getDeleteModal - returns a confirm-modal with delete option
+ */
+
+export const getCustomModal = (
+ runModal: (value: string) => void,
+ closeModal: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ labelTxt: string,
+ titletxt: string,
+ btn1txt: string,
+ btn2txt: string,
+ openNoteName?: string,
+ helpText?: string,
+) => {
+ return (
+
+ );
+};
+
+export const getCloneModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void
+) => {
+ return (
+
+
+ Do you want to clone this notebook?
+
+
+ );
+};
+
+export const getSampleNotebooksModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void
+) => {
+ return (
+
+
+ Do you want to add sample notebooks? This will also add Dashboards sample flights and logs data if they have not been added.
+
+
+ );
+};
+
+export const getDeleteModal = (
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void,
+ onConfirm: (event?: React.MouseEvent) => void,
+ title: string,
+ message: string,
+ confirmMessage?: string,
+) => {
+ return (
+
+
+ {message}
+
+
+ );
+};
+
+export const DeleteNotebookModal = ({
+ onCancel,
+ onConfirm,
+ title,
+ message,
+}: {
+ onCancel: (
+ event?: React.KeyboardEvent | React.MouseEvent
+ ) => void;
+ onConfirm: (event?: React.MouseEvent) => void;
+ title: string;
+ message: string;
+}) => {
+ const [value, setValue] = useState('');
+ const onChange = (e: React.ChangeEvent) => {
+ setValue(e.target.value);
+ };
+ return (
+
+
+
+ {title}
+
+
+
+ {message}
+ The action cannot be undone.
+
+
+
+ onChange(e)}
+ />
+
+
+
+
+
+ Cancel
+ onConfirm()}
+ color="danger"
+ fill
+ disabled={value !== 'delete'}
+ >
+ Delete
+
+
+
+
+ );
+};
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/reporting_context_menu_helper.tsx b/dashboards-observability/public/components/notebooks/components/helpers/reporting_context_menu_helper.tsx
new file mode 100644
index 000000000..a174da65b
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/reporting_context_menu_helper.tsx
@@ -0,0 +1,236 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { parse } from "url";
+
+const getReportSourceURL = (baseURI: string) => {
+ return baseURI.substr(baseURI.lastIndexOf('/') + 1, baseURI.length);
+}
+
+export const readDataReportToFile = async (
+ stream: string,
+ fileFormat: string,
+ fileName: string
+) => {
+ const blob = new Blob([stream]);
+ const url = URL.createObjectURL(blob);
+ let link = document.createElement('a');
+ link.setAttribute('href', url);
+ link.setAttribute('download', fileName);
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+};
+
+const getFileFormatPrefix = (fileFormat: string) => {
+ var fileFormatPrefix = 'data:' + fileFormat + ';base64,';
+ return fileFormatPrefix;
+};
+
+const readStreamToFile = async (
+ stream: string,
+ fileFormat: string,
+ fileName: string
+) => {
+ let link = document.createElement('a');
+ if (fileName.includes('csv')) {
+ readDataReportToFile(stream, fileFormat, fileName);
+ return;
+ }
+ let fileFormatPrefix = getFileFormatPrefix(fileFormat);
+ let url = fileFormatPrefix + stream;
+ if (typeof link.download !== 'string') {
+ window.open(url, '_blank');
+ return;
+ }
+ link.download = fileName;
+ link.href = url;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+};
+
+async function getTenantInfoIfExists() {
+ const res = await fetch(`../api/v1/multitenancy/tenant`, {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'osd-xsrf': 'true',
+ accept: '*/*',
+ 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6',
+ pragma: 'no-cache',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ },
+ method: 'GET',
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ mode: 'cors',
+ credentials: 'include',
+ })
+ .then((response) => {
+ if (response.status === 404) {
+ // endpoint doesn't exist, security plugin is not enabled.
+ return undefined;
+ } else {
+ return response.text();
+ }
+ })
+ .then((tenant) => {
+ if (tenant === '') {
+ tenant = 'global';
+ } else if (tenant === '__user__') {
+ tenant = 'private';
+ }
+ return tenant;
+ });
+
+ return res;
+}
+
+function addTenantToURL(url, userRequestedTenant) {
+ // build fake url from relative url
+ const fakeUrl = `http://opensearch.com${url}`;
+ const tenantKey = 'security_tenant';
+ const tenantKeyAndValue =
+ tenantKey + '=' + encodeURIComponent(userRequestedTenant);
+
+ const { pathname, search } = parse(fakeUrl);
+ const queryDelimiter = !search ? '?' : '&';
+ // The url parser returns null if the search is empty. Change that to an empty
+ // string so that we can use it to build the values later
+ if (search && search.toLowerCase().indexOf(tenantKey) > -1) {
+ // If we for some reason already have a tenant in the URL we skip any updates
+ return url;
+ }
+
+ // A helper for finding the part in the string that we want to extend/replace
+ const valueToReplace = pathname + (search || '');
+ const replaceWith = valueToReplace + queryDelimiter + tenantKeyAndValue;
+
+ return url.replace(valueToReplace, replaceWith);
+}
+
+export const generateInContextReport = async (
+ fileFormat: string,
+ props: any,
+ toggleReportingLoadingModal: any,
+ rest = {}
+) => {
+ toggleReportingLoadingModal(true);
+ let baseUrl =
+ location.pathname +
+ location.hash.replace(/\?view=(view_both|input_only|output_only)/, '') +
+ '?view=output_only';
+ // Add selected tenant info to url
+ try {
+ const tenant = await getTenantInfoIfExists();
+ if (tenant) {
+ baseUrl = addTenantToURL(baseUrl, tenant)
+ }
+ } catch (error) {
+ props.setToast(
+ 'Tenant error',
+ 'danger',
+ 'Failed to get user tenant.'
+ );
+ console.log(`failed to get user tenant: ${error}`);
+ }
+
+ const reportSource = 'Notebook';
+ const contextMenuOnDemandReport = {
+ query_url: baseUrl,
+ time_from: 0, // no time range for notebook reports
+ time_to: 0,
+ report_definition: {
+ report_params: {
+ report_name: 'In-context ' + document.getElementById('notebookTitle')?.innerText,
+ report_source: reportSource,
+ description: 'In-context report download',
+ core_params: {
+ base_url: baseUrl,
+ report_format: fileFormat,
+ time_duration: 'PT30M', // time duration can be hard-coded
+ ...rest,
+ },
+ },
+ delivery: {
+ configIds: [],
+ title: '',
+ textDescription: '',
+ htmlDescription: '',
+ },
+ trigger: {
+ trigger_type: 'On demand',
+ },
+ },
+ };
+ fetch(
+ '../api/reporting/generateReport',
+ {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'osd-xsrf': 'true',
+ accept: '*/*',
+ 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6',
+ pragma: 'no-cache',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ },
+ method: 'POST',
+ body: JSON.stringify(contextMenuOnDemandReport),
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ mode: 'cors',
+ credentials: 'include',
+ }
+ )
+ .then((response) => {
+ toggleReportingLoadingModal(false);
+ if (response.status === 200) {
+ // success toast
+ props.setToast('Successfully generated report.', 'success');
+ } else {
+ if (response.status === 403) {
+ // permissions failure toast
+ props.setToast(
+ 'Error generating report,',
+ 'danger',
+ 'Insufficient permissions. Reach out to your OpenSearch Dashboards administrator.'
+ );
+ } else if (response.status === 503) {
+ // timeout failure
+ props.setToast(
+ 'Error generating report.',
+ 'danger',
+ 'Timed out generating on-demand report from notebook. Try again later.'
+ );
+ } else {
+ // generic failure
+ props.setToast(
+ 'Download error',
+ 'danger',
+ 'There was an error generating this report.'
+ );
+ }
+ }
+ return response.json();
+ })
+ .then(async (data) => {
+ await readStreamToFile(data.data, fileFormat, data.filename);
+ })
+}
+
+export const contextMenuCreateReportDefinition = (baseURI: string) => {
+ const reportSourceId = getReportSourceURL(baseURI);
+ let reportSource = 'notebook:';
+
+ reportSource += reportSourceId.toString();
+ window.location.assign(
+ `reports-dashboards#/create?previous=${reportSource}?timeFrom=0?timeTo=0`
+ );
+};
+
+export const contextMenuViewReports = () =>
+ window.location.assign('reports-dashboards#/');
diff --git a/dashboards-observability/public/components/notebooks/components/helpers/zeppelin_parser.tsx b/dashboards-observability/public/components/notebooks/components/helpers/zeppelin_parser.tsx
new file mode 100644
index 000000000..f2293c3a7
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/helpers/zeppelin_parser.tsx
@@ -0,0 +1,149 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/* This file contains parsing functions
+ * These functions have to be changed based on backend configuration
+ * If backend changes the incoming paragraph structures may change, so parsing adapts to it
+ */
+
+import { ParaType } from '../../../common';
+
+const visualizationPrefix = '%sh #vizobject:';
+const observabilityVisualizationPrefix = '%sh #observabilityviz:';
+
+const langSupport = {
+ '%sh': 'shell',
+ '%md': 'md',
+ '%python': 'python',
+ '%opensearchsql': 'sql',
+ '%elasticsearch': 'json',
+};
+
+// Get the coding language from a Zeppelin paragraph input
+// Param: textHeader-> header on a Zeppelin paragraph example "%md"
+const parseCodeLanguage = (textHeader: string) => {
+ const codeLanguage = langSupport[textHeader];
+ return codeLanguage || '';
+};
+
+// Get the type of output message from a Zeppelin paragraph
+// Param: Zeppelin Paragraph
+const parseMessage = (paraObject: any) => {
+ try {
+ let mtype = [];
+ let mdata = [];
+ paraObject.results.msg.map((msg: { type: string; data: string }) => {
+ mtype.push(msg.type);
+ mdata.push(msg.data);
+ });
+ return {
+ outputType: mtype,
+ outputData: mdata,
+ };
+ } catch (error) {
+ return {
+ outputType: [],
+ outputData: [],
+ };
+ }
+};
+
+// Get the type of output message from a Zeppelin paragraph
+// Param: Zeppelin Paragraph
+const parseText = (paraObject: any) => {
+ if ('text' in paraObject) {
+ return paraObject.text;
+ } else {
+ throw new Error('Input text parse issue');
+ }
+};
+
+// Get the visualization from a Zeppelin Paragraph input
+// All Visualizations in Zeppelin are stored as shell comment -> "%sh #vizobject:"
+// TODO: This is a workaround need to look for better solutions
+// Param: Zeppelin Paragraph
+const parseVisualization = (paraObject: any) => {
+ let vizContent = '';
+ if (
+ paraObject.hasOwnProperty('text') &&
+ paraObject.text.substring(0, 15) === visualizationPrefix
+ ) {
+ if (paraObject.title !== 'VISUALIZATION') {
+ throw new Error('Visualization parse issue');
+ }
+ vizContent = paraObject.text.substring(15);
+ return {
+ isViz: true,
+ VizObject: vizContent,
+ };
+ }
+
+ if (
+ paraObject.hasOwnProperty('text') &&
+ paraObject.text.substring(0, 22) === observabilityVisualizationPrefix
+ ) {
+ if (paraObject.title !== 'OBSERVABILITY_VISUALIZATION') {
+ throw new Error('Visualization parse issue');
+ }
+ vizContent = paraObject.text.substring(22);
+ return {
+ isViz: true,
+ VizObject: vizContent,
+ };
+ }
+
+ return {
+ isViz: false,
+ VizObject: vizContent,
+ };
+};
+
+// This parser is used to get paragraph id
+// Param: Zeppelin Paragraph
+const parseId = (paraObject: any) => {
+ if ('id' in paraObject) {
+ return paraObject.id;
+ } else {
+ throw new Error('Id not found in paragraph');
+ }
+};
+
+// This parser helps to convert Zeppelin paragraphs to a common ParaType format
+// This parsing makes any backend notebook compatible with notebooks plugin
+export const zeppelinParagraphParser = (zeppelinBackendParagraphs: any) => {
+ let parsedPara: Array = [];
+ try {
+ zeppelinBackendParagraphs.map((paraObject: ParaType, index: number) => {
+ const paragraphId = parseId(paraObject);
+ const vizParams = parseVisualization(paraObject);
+ const inputParam = parseText(paraObject);
+ const codeLanguage = parseCodeLanguage(inputParam.split('\n')[0].split('.')[0]);
+ const message = parseMessage(paraObject);
+
+ let tempPara = {
+ uniqueId: paragraphId,
+ isRunning: false,
+ inQueue: false,
+ ishovered: false,
+ isSelected: false,
+ isInputHidden: false,
+ isOutputHidden: false,
+ showAddPara: false,
+ isVizualisation: vizParams.isViz,
+ vizObjectInput: vizParams.VizObject,
+ id: index + 1,
+ inp: inputParam,
+ lang: 'text/x-' + codeLanguage,
+ editorLanguage: codeLanguage,
+ typeOut: message.outputType,
+ out: message.outputData,
+ };
+ parsedPara.push(tempPara);
+ });
+ return parsedPara;
+ } catch (error) {
+ throw new Error('Parsing Paragraph Issue ' + error);
+ }
+};
diff --git a/dashboards-observability/public/components/notebooks/components/main.tsx b/dashboards-observability/public/components/notebooks/components/main.tsx
new file mode 100644
index 000000000..9ba18c8e7
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/main.tsx
@@ -0,0 +1,354 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable no-console */
+
+import { EuiGlobalToastList, EuiLink } from '@elastic/eui';
+import { Toast } from '@elastic/eui/src/components/toast/global_toast_list';
+import React, { ReactChild } from 'react';
+// eslint-disable-next-line @osd/eslint/module_migration
+import { Route, Switch } from 'react-router';
+import { HashRouter, RouteComponentProps } from 'react-router-dom';
+import PPLService from '../../../services/requests/ppl';
+import { ChromeBreadcrumb, CoreStart } from '../../../../../../src/core/public';
+import { DashboardStart } from '../../../../../../src/plugins/dashboard/public';
+import {
+ NOTEBOOKS_API_PREFIX,
+ NOTEBOOKS_DOCUMENTATION_URL,
+} from '../../../../common/constants/notebooks';
+import { ObservabilitySideBar } from '../../common/side_nav';
+import { Notebook } from './notebook';
+import { NoteTable } from './note_table';
+
+/*
+ * "Main" component renders the whole Notebooks as a single page application
+ *
+ * Props taken in as params are:
+ * DashboardContainerByValueRenderer: Dashboard container renderer for visualization
+ * http object: for making API requests
+ *
+ * Cell component of nteract used as a container for paragraphs in notebook UI.
+ * https://components.nteract.io/#cell
+ */
+
+type MainProps = RouteComponentProps & {
+ DashboardContainerByValueRenderer: DashboardStart['DashboardContainerByValueRenderer'];
+ http: CoreStart['http'];
+ pplService: PPLService;
+ notifications: CoreStart['notifications'];
+ parentBreadcrumb: ChromeBreadcrumb;
+ setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
+};
+
+interface MainState {
+ data: NotebookType[];
+ openedNotebook: NotebookType | undefined;
+ toasts: Toast[];
+ loading: boolean;
+}
+
+export interface NotebookType {
+ path: string;
+ id: string;
+ dateCreated: string;
+ dateModified: string;
+}
+
+export class Main extends React.Component {
+ constructor(props: Readonly) {
+ super(props);
+ this.state = {
+ data: [],
+ openedNotebook: undefined,
+ toasts: [],
+ loading: false,
+ };
+ }
+
+ setToast = (title: string, color = 'success', text?: ReactChild) => {
+ if (!text) text = '';
+ this.setState((prevState) => ({
+ toasts: [
+ ...prevState.toasts,
+ {
+ id: new Date().toISOString(),
+ title,
+ text,
+ color,
+ } as Toast,
+ ],
+ }));
+ };
+
+ // Fetches path and id for all stored notebooks
+ fetchNotebooks = () => {
+ return this.props.http
+ .get(`${NOTEBOOKS_API_PREFIX}/`)
+ .then((res) => this.setState(res))
+ .catch((err) => {
+ console.error('Issue in fetching the notebooks', err.body.message);
+ });
+ };
+
+ // Creates a new notebook
+ createNotebook = (newNoteName: string) => {
+ if (newNoteName.length >= 50 || newNoteName.length === 0) {
+ this.setToast('Invalid notebook name', 'danger');
+ return;
+ }
+ const newNoteObject = {
+ name: newNoteName,
+ };
+
+ return this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/note`, {
+ body: JSON.stringify(newNoteObject),
+ })
+ .then(async (res) => {
+ this.setToast(`Notebook "${newNoteName}" successfully created!`);
+ window.location.assign(`#/notebooks/${res}`);
+ })
+ .catch((err) => {
+ this.setToast(
+ 'Please ask your administrator to enable Notebooks for you.',
+ 'danger',
+
+ Documentation
+
+ );
+ console.error(err);
+ });
+ };
+
+ // Renames an existing notebook
+ renameNotebook = (editedNoteName: string, editedNoteID: string) => {
+ if (editedNoteName.length >= 50 || editedNoteName.length === 0) {
+ this.setToast('Invalid notebook name', 'danger');
+ return;
+ }
+ const renameNoteObject = {
+ name: editedNoteName,
+ noteId: editedNoteID,
+ };
+
+ return this.props.http
+ .put(`${NOTEBOOKS_API_PREFIX}/note/rename`, {
+ body: JSON.stringify(renameNoteObject),
+ })
+ .then((res) => {
+ this.setState((prevState) => {
+ const newData = [...prevState.data];
+ const renamedNotebook = newData.find((notebook) => notebook.id === editedNoteID);
+ if (renamedNotebook) renamedNotebook.path = editedNoteName;
+ return { data: newData };
+ });
+ this.setToast(`Notebook successfully renamed into "${editedNoteName}"`);
+ })
+ .catch((err) => {
+ this.setToast(
+ 'Error renaming notebook, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Clones an existing notebook, return new notebook's id
+ cloneNotebook = (clonedNoteName: string, clonedNoteID: string): Promise => {
+ if (clonedNoteName.length >= 50 || clonedNoteName.length === 0) {
+ this.setToast('Invalid notebook name', 'danger');
+ return Promise.reject();
+ }
+ const cloneNoteObject = {
+ name: clonedNoteName,
+ noteId: clonedNoteID,
+ };
+
+ return this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/note/clone`, {
+ body: JSON.stringify(cloneNoteObject),
+ })
+ .then((res) => {
+ this.setState((prevState) => ({
+ data: [
+ ...prevState.data,
+ {
+ path: clonedNoteName,
+ id: res.body.id,
+ dateCreated: res.body.dateCreated,
+ dateModified: res.body.dateModified,
+ },
+ ],
+ }));
+ this.setToast(`Notebook "${clonedNoteName}" successfully created!`);
+ return res.body.id;
+ })
+ .catch((err) => {
+ this.setToast(
+ 'Error cloning notebook, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Deletes existing notebooks
+ deleteNotebook = (notebookList: string[], toastMessage?: string) => {
+ return this.props.http
+ .delete(`${NOTEBOOKS_API_PREFIX}/note/${notebookList.join(',')}`)
+ .then((res) => {
+ this.setState((prevState) => ({
+ data: prevState.data.filter((notebook) => !notebookList.includes(notebook.id)),
+ }));
+ const message =
+ toastMessage || `Notebook${notebookList.length > 1 ? 's' : ''} successfully deleted!`;
+ this.setToast(message);
+ return res;
+ })
+ .catch((err) => {
+ this.setToast(
+ 'Error deleting notebook, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ addSampleNotebooks = async () => {
+ try {
+ this.setState({ loading: true });
+ const flights = await this.props.http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_flights',
+ },
+ })
+ .then((resp) => resp.total === 0);
+ const logs = await this.props.http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'index-pattern',
+ search_fields: 'title',
+ search: 'opensearch_dashboards_sample_data_logs',
+ },
+ })
+ .then((resp) => resp.total === 0);
+ if (flights || logs) this.setToast('Adding sample data. This can take some time.');
+ await Promise.all([
+ flights ? this.props.http.post('../api/sample_data/flights') : Promise.resolve(),
+ logs ? this.props.http.post('../api/sample_data/logs') : Promise.resolve(),
+ ]);
+ const visIds: string[] = [];
+ await this.props.http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'visualization',
+ search_fields: 'title',
+ search: '[Logs] Response Codes Over Time + Annotations',
+ },
+ })
+ .then((resp) => visIds.push(resp.saved_objects[0].id));
+ await this.props.http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'visualization',
+ search_fields: 'title',
+ search: '[Logs] Unique Visitors vs. Average Bytes',
+ },
+ })
+ .then((resp) => visIds.push(resp.saved_objects[0].id));
+ await this.props.http
+ .get('../api/saved_objects/_find', {
+ query: {
+ type: 'visualization',
+ search_fields: 'title',
+ search: '[Flights] Flight Count and Average Ticket Price',
+ },
+ })
+ .then((resp) => visIds.push(resp.saved_objects[0].id));
+ await this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/note/addSampleNotebooks`, {
+ body: JSON.stringify({ visIds }),
+ })
+ .then((res) => {
+ const newData = res.body.map((notebook: any) => ({
+ path: notebook.name,
+ id: notebook.id,
+ dateCreated: notebook.dateCreated,
+ dateModified: notebook.dateModified,
+ }));
+ this.setState((prevState) => ({
+ data: [...prevState.data, ...newData],
+ }));
+ });
+ this.setToast(`Sample notebooks successfully added.`);
+ } catch (err: any) {
+ this.setToast('Error adding sample notebooks.', 'danger');
+ console.error(err.body.message);
+ } finally {
+ this.setState({ loading: false });
+ }
+ };
+
+ render() {
+ return (
+
+ <>
+ {
+ this.setState({
+ toasts: this.state.toasts.filter((toast) => toast.id !== removedToast.id),
+ });
+ }}
+ toastLifeTimeMs={6000}
+ />
+
+ (
+
+ )}
+ />
+ (
+
+
+
+ )}
+ />
+
+ >
+
+ );
+ }
+}
diff --git a/dashboards-observability/public/components/notebooks/components/note_table.tsx b/dashboards-observability/public/components/notebooks/components/note_table.tsx
new file mode 100644
index 000000000..d7ba77625
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/note_table.tsx
@@ -0,0 +1,393 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiContextMenuItem,
+ EuiContextMenuPanel,
+ EuiFieldSearch,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiHorizontalRule,
+ EuiInMemoryTable,
+ EuiLink,
+ EuiOverlayMask,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiPopover,
+ EuiSpacer,
+ EuiTableFieldDataColumnType,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import _ from 'lodash';
+import moment from 'moment';
+import React, { ReactElement, useEffect, useState } from 'react';
+import { ChromeBreadcrumb } from '../../../../../../src/core/public';
+import {
+ CREATE_NOTE_MESSAGE,
+ NOTEBOOKS_DOCUMENTATION_URL,
+} from '../../../../common/constants/notebooks';
+import { UI_DATE_FORMAT } from '../../../../common/constants/shared';
+import {
+ DeleteNotebookModal,
+ getCustomModal,
+ getSampleNotebooksModal,
+} from './helpers/modal_containers';
+import { NotebookType } from './main';
+import { pageStyles } from '../../../../common/constants/shared';
+
+interface NoteTableProps {
+ loading: boolean;
+ fetchNotebooks: () => void;
+ addSampleNotebooks: () => void;
+ notebooks: NotebookType[];
+ createNotebook: (newNoteName: string) => void;
+ renameNotebook: (newNoteName: string, noteId: string) => void;
+ cloneNotebook: (newNoteName: string, noteId: string) => void;
+ deleteNotebook: (noteList: string[], toastMessage?: string) => void;
+ parentBreadcrumb: ChromeBreadcrumb;
+ setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
+ setToast: (title: string, color?: string, text?: string) => void;
+}
+
+export function NoteTable(props: NoteTableProps) {
+ const [isModalVisible, setIsModalVisible] = useState(false); // Modal Toggle
+ const [modalLayout, setModalLayout] = useState( ); // Modal Layout
+ const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false);
+ const [selectedNotebooks, setSelectedNotebooks] = useState([]);
+ const [searchQuery, setSearchQuery] = useState('');
+ const { notebooks, createNotebook, renameNotebook, cloneNotebook, deleteNotebook } = props;
+
+ useEffect(() => {
+ props.setBreadcrumbs([
+ props.parentBreadcrumb,
+ {
+ text: 'Notebooks',
+ href: '#/notebooks',
+ },
+ ]);
+ props.fetchNotebooks();
+ }, []);
+
+ const closeModal = () => {
+ setIsModalVisible(false);
+ };
+ const showModal = () => {
+ setIsModalVisible(true);
+ };
+
+ const onCreate = async (newNoteName: string) => {
+ createNotebook(newNoteName);
+ closeModal();
+ };
+
+ const onRename = async (newNoteName: string) => {
+ renameNotebook(newNoteName, selectedNotebooks[0].id);
+ closeModal();
+ };
+
+ const onClone = async (newName: string) => {
+ cloneNotebook(newName, selectedNotebooks[0].id);
+ closeModal();
+ };
+
+ const onDelete = async () => {
+ const toastMessage = `Notebook${
+ selectedNotebooks.length > 1 ? 's' : ' "' + selectedNotebooks[0].path + '"'
+ } successfully deleted!`;
+ await deleteNotebook(
+ selectedNotebooks.map((note) => note.id),
+ toastMessage
+ );
+ closeModal();
+ };
+
+ const createNote = () => {
+ setModalLayout(
+ getCustomModal(
+ onCreate,
+ closeModal,
+ 'Name',
+ 'Create notebook',
+ 'Cancel',
+ 'Create',
+ undefined,
+ CREATE_NOTE_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const renameNote = () => {
+ setModalLayout(
+ getCustomModal(
+ onRename,
+ closeModal,
+ 'Name',
+ 'Rename notebook',
+ 'Cancel',
+ 'Rename',
+ selectedNotebooks[0].path,
+ CREATE_NOTE_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const cloneNote = () => {
+ setModalLayout(
+ getCustomModal(
+ onClone,
+ closeModal,
+ 'Name',
+ 'Duplicate notebook',
+ 'Cancel',
+ 'Duplicate',
+ selectedNotebooks[0].path + ' (copy)',
+ CREATE_NOTE_MESSAGE
+ )
+ );
+ showModal();
+ };
+
+ const deleteNote = () => {
+ const notebookString = `notebook${selectedNotebooks.length > 1 ? 's' : ''}`;
+ setModalLayout(
+
+ );
+ showModal();
+ };
+
+ const addSampleNotebooks = async () => {
+ setModalLayout(
+ getSampleNotebooksModal(closeModal, async () => {
+ closeModal();
+ await props.addSampleNotebooks();
+ })
+ );
+ showModal();
+ };
+
+ const popoverButton = (
+ setIsActionsPopoverOpen(!isActionsPopoverOpen)}
+ >
+ Actions
+
+ );
+
+ const popoverItems: ReactElement[] = [
+ {
+ setIsActionsPopoverOpen(false);
+ renameNote();
+ }}
+ >
+ Rename
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ cloneNote();
+ }}
+ >
+ Duplicate
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ deleteNote();
+ }}
+ >
+ Delete
+ ,
+ {
+ setIsActionsPopoverOpen(false);
+ addSampleNotebooks();
+ }}
+ >
+ Add samples
+ ,
+ ];
+
+ const tableColumns = [
+ {
+ field: 'path',
+ name: 'Name',
+ sortable: true,
+ truncateText: true,
+ render: (value, record) => (
+ {_.truncate(value, { length: 100 })}
+ ),
+ },
+ {
+ field: 'dateModified',
+ name: 'Last updated',
+ sortable: true,
+ render: (value) => moment(value).format(UI_DATE_FORMAT),
+ },
+ {
+ field: 'dateCreated',
+ name: 'Created',
+ sortable: true,
+ render: (value) => moment(value).format(UI_DATE_FORMAT),
+ },
+ ] as Array<
+ EuiTableFieldDataColumnType<{
+ path: string;
+ id: string;
+ dateCreated: string;
+ dateModified: string;
+ }>
+ >;
+
+ return (
+
+
+
+
+
+
+ Notebooks
+
+
+
+
+
+
+
+
+ Notebooks ({notebooks.length})
+
+
+
+
+ Use Notebooks to interactively and collaboratively develop rich reports backed by
+ live data. Common use cases for notebooks includes creating postmortem reports,
+ designing run books, building live infrastructure reports, or even documentation.{' '}
+
+ Learn more
+
+
+
+
+
+
+ setIsActionsPopoverOpen(false)}
+ >
+
+
+
+
+ createNote()}>
+ Create notebook
+
+
+
+
+
+
+ {notebooks.length > 0 ? (
+ <>
+ setSearchQuery(e.target.value)}
+ />
+
+
+ notebook.path.toLowerCase().includes(searchQuery.toLowerCase())
+ )
+ : notebooks
+ }
+ itemId="id"
+ columns={tableColumns}
+ tableLayout="auto"
+ pagination={{
+ initialPageSize: 10,
+ pageSizeOptions: [8, 10, 13],
+ }}
+ sorting={{
+ sort: {
+ field: 'dateModified',
+ direction: 'desc',
+ },
+ }}
+ allowNeutralSort={false}
+ isSelectable={true}
+ selection={{
+ onSelectionChange: (items) => setSelectedNotebooks(items),
+ }}
+ />
+ >
+ ) : (
+ <>
+
+
+ No notebooks
+
+
+ Use notebooks to create post-mortem reports, build live infrastructure
+
+ reports, or foster explorative collaborations with data.
+
+
+
+
+
+ createNote()}
+ >
+ Create notebook
+
+
+
+ addSampleNotebooks()}>
+ Add samples
+
+
+
+
+ >
+ )}
+
+
+
+ {isModalVisible && modalLayout}
+
+ );
+}
diff --git a/dashboards-observability/public/components/notebooks/components/notebook.tsx b/dashboards-observability/public/components/notebooks/components/notebook.tsx
new file mode 100644
index 000000000..b97ab1723
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/notebook.tsx
@@ -0,0 +1,1113 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiButtonGroup,
+ EuiButtonGroupOption,
+ EuiCard,
+ EuiContextMenu,
+ EuiContextMenuPanelDescriptor,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiIcon,
+ EuiOverlayMask,
+ EuiPage,
+ EuiPageBody,
+ EuiPanel,
+ EuiPopover,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import CSS from 'csstype';
+import moment from 'moment';
+import PPLService from '../../../services/requests/ppl';
+import queryString from 'query-string';
+import React, { Component } from 'react';
+import { RouteComponentProps } from 'react-router-dom';
+import { ChromeBreadcrumb, CoreStart } from '../../../../../../src/core/public';
+import { DashboardStart } from '../../../../../../src/plugins/dashboard/public';
+import {
+ CREATE_NOTE_MESSAGE,
+ NOTEBOOKS_API_PREFIX,
+ NOTEBOOKS_SELECTED_BACKEND,
+} from '../../../../common/constants/notebooks';
+import { UI_DATE_FORMAT } from '../../../../common/constants/shared';
+import { ParaType } from '../../../../common/types/notebooks';
+import { GenerateReportLoadingModal } from './helpers/custom_modals/reporting_loading_modal';
+import { defaultParagraphParser } from './helpers/default_parser';
+import { DeleteNotebookModal, getCustomModal, getDeleteModal } from './helpers/modal_containers';
+import {
+ contextMenuCreateReportDefinition,
+ contextMenuViewReports,
+ generateInContextReport,
+} from './helpers/reporting_context_menu_helper';
+import { zeppelinParagraphParser } from './helpers/zeppelin_parser';
+import { Paragraphs } from './paragraph_components/paragraphs';
+const panelStyles: CSS.Properties = {
+ float: 'left',
+ width: '100%',
+ maxWidth: '1130px',
+ marginTop: '20px',
+};
+
+const pageStyles: CSS.Properties = {
+ float: 'left',
+ width: '100%',
+ maxWidth: '1500px',
+};
+
+/*
+ * "Notebook" component is used to display an open notebook
+ *
+ * Props taken in as params are:
+ * DashboardContainerByValueRenderer - Dashboard container renderer for visualization
+ * http object - for making API requests
+ * setBreadcrumbs - sets breadcrumbs on top
+ */
+type NotebookProps = {
+ pplService: PPLService;
+ openedNoteId: string;
+ DashboardContainerByValueRenderer: DashboardStart['DashboardContainerByValueRenderer'];
+ http: CoreStart['http'];
+ parentBreadcrumb: ChromeBreadcrumb;
+ setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
+ renameNotebook: (newNoteName: string, noteId: string) => void;
+ cloneNotebook: (newNoteName: string, noteId: string) => Promise;
+ deleteNotebook: (noteList: string[], toastMessage?: string) => void;
+ setToast: (title: string, color?: string, text?: string) => void;
+ location: RouteComponentProps['location'];
+ history: RouteComponentProps['history'];
+};
+
+type NotebookState = {
+ selectedViewId: string;
+ path: string;
+ dateCreated: string;
+ dateModified: string;
+ paragraphs: any; // notebook paragraphs fetched from API
+ parsedPara: Array; // paragraphs parsed to a common format
+ vizPrefix: string; // prefix for visualizations in Zeppelin Adaptor
+ isAddParaPopoverOpen: boolean;
+ isParaActionsPopoverOpen: boolean;
+ isNoteActionsPopoverOpen: boolean;
+ isReportingPluginInstalled: boolean;
+ isReportingActionsPopoverOpen: boolean;
+ isReportingLoadingModalOpen: boolean;
+ isModalVisible: boolean;
+ modalLayout: React.ReactNode;
+ showQueryParagraphError: boolean;
+ queryParagraphErrorMessage: string;
+};
+export class Notebook extends Component {
+ constructor(props: Readonly) {
+ super(props);
+ this.state = {
+ selectedViewId: 'view_both',
+ path: '',
+ dateCreated: '',
+ dateModified: '',
+ paragraphs: [],
+ parsedPara: [],
+ vizPrefix: '',
+ isAddParaPopoverOpen: false,
+ isParaActionsPopoverOpen: false,
+ isNoteActionsPopoverOpen: false,
+ isReportingPluginInstalled: false,
+ isReportingActionsPopoverOpen: false,
+ isReportingLoadingModalOpen: false,
+ isModalVisible: false,
+ modalLayout: ,
+ showQueryParagraphError: false,
+ queryParagraphErrorMessage: '',
+ };
+ }
+
+ toggleReportingLoadingModal = (show: boolean) => {
+ this.setState({ isReportingLoadingModalOpen: show });
+ };
+
+ parseAllParagraphs = () => {
+ let parsedPara = this.parseParagraphs(this.state.paragraphs);
+ this.setState({ parsedPara });
+ };
+
+ // parse paragraphs based on backend
+ parseParagraphs = (paragraphs: any[]): ParaType[] => {
+ try {
+ let parsedPara;
+ // @ts-ignore
+ if (NOTEBOOKS_SELECTED_BACKEND === 'ZEPPELIN') {
+ parsedPara = zeppelinParagraphParser(paragraphs);
+ this.setState({ vizPrefix: '%sh #vizobject:' });
+ } else {
+ parsedPara = defaultParagraphParser(paragraphs);
+ }
+ parsedPara.forEach((para: ParaType) => {
+ para.isInputExpanded = this.state.selectedViewId === 'input_only';
+ para.paraRef = React.createRef();
+ para.paraDivRef = React.createRef();
+ });
+ return parsedPara;
+ } catch (err) {
+ this.props.setToast(
+ 'Error parsing paragraphs, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err);
+ this.setState({ parsedPara: [] });
+ return [];
+ }
+ };
+
+ // Assigns Loading, Running & inQueue for paragraphs in current notebook
+ showParagraphRunning = (param: number | string) => {
+ let parsedPara = this.state.parsedPara;
+ this.state.parsedPara.map((_: ParaType, index: number) => {
+ if (param === 'queue') {
+ parsedPara[index].inQueue = true;
+ parsedPara[index].isOutputHidden = true;
+ } else if (param === 'loading') {
+ parsedPara[index].isRunning = true;
+ parsedPara[index].isOutputHidden = true;
+ } else if (param === index) {
+ parsedPara[index].isRunning = true;
+ parsedPara[index].isOutputHidden = true;
+ }
+ });
+ this.setState({ parsedPara });
+ };
+
+ // Sets a paragraph to selected and deselects all others
+ paragraphSelector = (index: number) => {
+ let parsedPara = this.state.parsedPara;
+ this.state.parsedPara.map((_: ParaType, idx: number) => {
+ if (index === idx) parsedPara[idx].isSelected = true;
+ else parsedPara[idx].isSelected = false;
+ });
+ this.setState({ parsedPara });
+ };
+
+ // Function for delete a Notebook button
+ deleteParagraphButton = (para: ParaType, index: number) => {
+ if (index !== -1) {
+ return this.props.http
+ .delete(`${NOTEBOOKS_API_PREFIX}/paragraph`, {
+ query: {
+ noteId: this.props.openedNoteId,
+ paragraphId: para.uniqueId,
+ },
+ })
+ .then((res) => {
+ const paragraphs = [...this.state.paragraphs];
+ paragraphs.splice(index, 1);
+ const parsedPara = [...this.state.parsedPara];
+ parsedPara.splice(index, 1);
+ this.setState({ paragraphs, parsedPara });
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error deleting paragraph, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ }
+ };
+
+ showDeleteParaModal = (para: ParaType, index: number) => {
+ this.setState({
+ modalLayout: getDeleteModal(
+ () => this.setState({ isModalVisible: false }),
+ () => {
+ this.deleteParagraphButton(para, index);
+ this.setState({ isModalVisible: false });
+ },
+ 'Delete paragraph',
+ 'Are you sure you want to delete the paragraph? The action cannot be undone.'
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ showDeleteAllParaModal = () => {
+ this.setState({
+ modalLayout: getDeleteModal(
+ () => this.setState({ isModalVisible: false }),
+ async () => {
+ this.setState({ isModalVisible: false });
+ await this.props.http
+ .delete(`${NOTEBOOKS_API_PREFIX}/paragraph`, {
+ query: {
+ noteId: this.props.openedNoteId,
+ },
+ })
+ .then((res) => {
+ this.setState({ paragraphs: res.paragraphs });
+ this.parseAllParagraphs();
+ this.props.setToast('Paragraphs successfully deleted!');
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error deleting paragraph, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ },
+ 'Delete all paragraphs',
+ 'Are you sure you want to delete all paragraphs? The action cannot be undone.'
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ showClearOutputsModal = () => {
+ this.setState({
+ modalLayout: getDeleteModal(
+ () => this.setState({ isModalVisible: false }),
+ () => {
+ this.clearParagraphButton();
+ this.setState({ isModalVisible: false });
+ },
+ 'Clear all outputs',
+ 'Are you sure you want to clear all outputs? The action cannot be undone.',
+ 'Clear'
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ showRenameModal = () => {
+ this.setState({
+ modalLayout: getCustomModal(
+ (newName: string) => {
+ this.props.renameNotebook(newName, this.props.openedNoteId);
+ this.setState({ isModalVisible: false });
+ this.loadNotebook();
+ },
+ () => this.setState({ isModalVisible: false }),
+ 'Name',
+ 'Rename notebook',
+ 'Cancel',
+ 'Rename',
+ this.state.path,
+ CREATE_NOTE_MESSAGE
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ showCloneModal = () => {
+ this.setState({
+ modalLayout: getCustomModal(
+ (newName: string) => {
+ this.props.cloneNotebook(newName, this.props.openedNoteId).then((id: string) => {
+ window.location.assign(`#/notebooks/${id}`);
+ setTimeout(() => {
+ this.loadNotebook();
+ }, 300);
+ });
+ this.setState({ isModalVisible: false });
+ },
+ () => this.setState({ isModalVisible: false }),
+ 'Name',
+ 'Duplicate notebook',
+ 'Cancel',
+ 'Duplicate',
+ this.state.path + ' (copy)',
+ CREATE_NOTE_MESSAGE
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ showDeleteNotebookModal = () => {
+ this.setState({
+ modalLayout: (
+ {
+ const toastMessage = `Notebook "${this.state.path}" successfully deleted!`;
+ await this.props.deleteNotebook([this.props.openedNoteId], toastMessage);
+ this.setState({ isModalVisible: false }, () =>
+ setTimeout(() => {
+ this.props.history.push('.');
+ }, 1000)
+ );
+ }}
+ onCancel={() => this.setState({ isModalVisible: false })}
+ title={`Delete notebook "${this.state.path}"`}
+ message="Delete notebook will remove all contents in the paragraphs."
+ />
+ ),
+ });
+ this.setState({ isModalVisible: true });
+ };
+
+ // Function for delete Visualization from notebook
+ deleteVizualization = (uniqueId: string) => {
+ this.props.http
+ .delete(`${NOTEBOOKS_API_PREFIX}/paragraph/` + this.props.openedNoteId + '/' + uniqueId)
+ .then((res) => {
+ this.setState({ paragraphs: res.paragraphs });
+ this.parseAllParagraphs();
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error deleting visualization, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Backend call to add a paragraph, switch to "view both" if in output only view
+ addPara = (index: number, newParaContent: string, inpType: string) => {
+ const addParaObj = {
+ noteId: this.props.openedNoteId,
+ paragraphIndex: index,
+ paragraphInput: newParaContent,
+ inputType: inpType,
+ };
+
+ return this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/paragraph/`, {
+ body: JSON.stringify(addParaObj),
+ })
+ .then((res) => {
+ const paragraphs = [...this.state.paragraphs];
+ paragraphs.splice(index, 0, res);
+ const newPara = this.parseParagraphs([res])[0];
+ newPara.isInputExpanded = true;
+ const parsedPara = [...this.state.parsedPara];
+ parsedPara.splice(index, 0, newPara);
+
+ this.setState({ paragraphs, parsedPara });
+ this.paragraphSelector(index);
+ if (this.state.selectedViewId === 'output_only')
+ this.setState({ selectedViewId: 'view_both' });
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error adding paragraph, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Function to clone a paragraph
+ cloneParaButton = (para: ParaType, index: number) => {
+ let inputType = 'CODE';
+ if (para.typeOut[0] === 'VISUALIZATION') {
+ inputType = 'VISUALIZATION';
+ }
+ if (para.typeOut[0] === 'OBSERVABILITY_VISUALIZATION') {
+ inputType = 'OBSERVABILITY_VISUALIZATION';
+ }
+ if (index !== -1) {
+ return this.addPara(index, para.inp, inputType);
+ }
+ };
+
+ // Function to move a paragraph
+ movePara = (index: number, targetIndex: number) => {
+ const paragraphs = [...this.state.paragraphs];
+ paragraphs.splice(targetIndex, 0, paragraphs.splice(index, 1)[0]);
+ const parsedPara = [...this.state.parsedPara];
+ parsedPara.splice(targetIndex, 0, parsedPara.splice(index, 1)[0]);
+
+ const moveParaObj = {
+ noteId: this.props.openedNoteId,
+ paragraphs,
+ };
+
+ return this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/set_paragraphs/`, {
+ body: JSON.stringify(moveParaObj),
+ })
+ .then((res) => this.setState({ paragraphs, parsedPara }))
+ .then((res) => this.scrollToPara(targetIndex))
+ .catch((err) => {
+ this.props.setToast(
+ 'Error moving paragraphs, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ scrollToPara(index: number) {
+ setTimeout(() => {
+ window.scrollTo({
+ left: 0,
+ top: this.state.parsedPara[index].paraDivRef.current?.offsetTop,
+ behavior: 'smooth',
+ });
+ }, 0);
+ }
+
+ // Function for clearing outputs button
+ clearParagraphButton = () => {
+ this.showParagraphRunning('loading');
+ const clearParaObj = {
+ noteId: this.props.openedNoteId,
+ };
+ this.props.http
+ .put(`${NOTEBOOKS_API_PREFIX}/paragraph/clearall/`, {
+ body: JSON.stringify(clearParaObj),
+ })
+ .then((res) => {
+ this.setState({ paragraphs: res.paragraphs });
+ this.parseAllParagraphs();
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error clearing paragraphs, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ // Backend call to update and run contents of paragraph
+ updateRunParagraph = (
+ para: ParaType,
+ index: number,
+ vizObjectInput?: string,
+ paraType?: string
+ ) => {
+ this.showParagraphRunning(index);
+ if (vizObjectInput) {
+ para.inp = this.state.vizPrefix + vizObjectInput; // "%sh check"
+ }
+
+ const paraUpdateObject = {
+ noteId: this.props.openedNoteId,
+ paragraphId: para.uniqueId,
+ paragraphInput: para.inp,
+ paragraphType: paraType || '',
+ };
+
+ return this.props.http
+ .post(`${NOTEBOOKS_API_PREFIX}/paragraph/update/run/`, {
+ body: JSON.stringify(paraUpdateObject),
+ })
+ .then(async (res) => {
+ if (res.output[0]?.outputType === 'QUERY') {
+ await this.loadQueryResultsFromInput(res);
+ const checkErrorJSON = JSON.parse(res.output[0].result);
+ if (this.checkQueryOutputError(checkErrorJSON)) {
+ return;
+ }
+ }
+ const paragraphs = this.state.paragraphs;
+ paragraphs[index] = res;
+ const parsedPara = [...this.state.parsedPara];
+ parsedPara[index] = this.parseParagraphs([res])[0];
+ this.setState({ paragraphs, parsedPara });
+ })
+ .catch((err) => {
+ if (err.body.statusCode === 413)
+ this.props.setToast(`Error running paragraph: ${err.body.message}`, 'danger');
+ else
+ this.props.setToast(
+ 'Error running paragraph, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err.body.message);
+ });
+ };
+
+ checkQueryOutputError = (checkErrorJSON: JSON) => {
+ // if query output has error output
+ if (checkErrorJSON.hasOwnProperty('error')) {
+ this.setState({
+ showQueryParagraphError: true,
+ queryParagraphErrorMessage: checkErrorJSON.error.reason,
+ });
+ return true;
+ }
+ // query ran successfully, reset error variables if currently set to true
+ else if (this.state.showQueryParagraphError) {
+ this.setState({
+ showQueryParagraphError: false,
+ queryParagraphErrorMessage: '',
+ });
+ return false;
+ }
+ };
+
+ runForAllParagraphs = (reducer: (para: ParaType, index: number) => Promise) => {
+ return this.state.parsedPara
+ .map((para: ParaType, index: number) => () => reducer(para, index))
+ .reduce((chain, func) => chain.then(func), Promise.resolve());
+ };
+
+ // Handles text editor value and syncs with paragraph input
+ textValueEditor = (evt: React.ChangeEvent, index: number) => {
+ if (!(evt.key === 'Enter' && evt.shiftKey)) {
+ let parsedPara = this.state.parsedPara;
+ parsedPara[index].inp = evt.target.value;
+ this.setState({ parsedPara });
+ }
+ };
+
+ // Handles run paragraph shortcut "Shift+Enter"
+ handleKeyPress = (evt: React.KeyboardEvent, para: ParaType, index: number) => {
+ if (evt.key === 'Enter' && evt.shiftKey) {
+ this.updateRunParagraph(para, index);
+ }
+ };
+
+ // update view mode, scrolls to paragraph and expands input if scrollToIndex is given
+ updateView = (selectedViewId: string, scrollToIndex?: number) => {
+ this.configureViewParameter(selectedViewId);
+ let parsedPara = [...this.state.parsedPara];
+ this.state.parsedPara.map((para: ParaType, index: number) => {
+ parsedPara[index].isInputExpanded = selectedViewId === 'input_only';
+ });
+
+ if (scrollToIndex !== undefined) {
+ parsedPara[scrollToIndex].isInputExpanded = true;
+ this.scrollToPara(scrollToIndex);
+ }
+ this.setState({ parsedPara, selectedViewId });
+ this.paragraphSelector(scrollToIndex !== undefined ? scrollToIndex : -1);
+ };
+
+ loadNotebook = () => {
+ this.showParagraphRunning('queue');
+ this.props.http
+ .get(`${NOTEBOOKS_API_PREFIX}/note/` + this.props.openedNoteId)
+ .then(async (res) => {
+ this.setBreadcrumbs(res.path);
+ let index = 0;
+ for (index = 0; index < res.paragraphs.length; ++index) {
+ // if the paragraph is a query, load the query output
+ if (res.paragraphs[index].output[0]?.outputType === 'QUERY') {
+ await this.loadQueryResultsFromInput(res.paragraphs[index]);
+ }
+ }
+ this.setState(res, this.parseAllParagraphs);
+ })
+ .catch((err) => {
+ this.props.setToast(
+ 'Error fetching notebooks, please make sure you have the correct permission.',
+ 'danger'
+ );
+ console.error(err?.body?.message || err);
+ });
+ };
+
+ loadQueryResultsFromInput = async (paragraph: any) => {
+ const queryType =
+ paragraph.input.inputText.substring(0, 4) === '%sql' ? 'sqlquery' : 'pplquery';
+ await this.props.http
+ .post(`/api/sql/${queryType}`, {
+ body: JSON.stringify(paragraph.output[0].result),
+ })
+ .then((response) => {
+ paragraph.output[0].result = response.data.resp;
+ return paragraph;
+ })
+ .catch((err) => {
+ this.props.setToast('Error getting query output', 'danger');
+ console.error(err);
+ });
+ };
+
+ setPara = (para: ParaType, index: number) => {
+ const parsedPara = [...this.state.parsedPara];
+ parsedPara.splice(index, 1, para);
+ this.setState({ parsedPara });
+ };
+
+ setBreadcrumbs(path: string) {
+ this.props.setBreadcrumbs([
+ this.props.parentBreadcrumb,
+ {
+ text: 'Notebooks',
+ href: '#/notebooks',
+ },
+ {
+ text: path,
+ href: `#/notebooks/${this.props.openedNoteId}`,
+ },
+ ]);
+ }
+
+ checkIfReportingPluginIsInstalled() {
+ fetch('../api/status', {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'osd-xsrf': 'true',
+ 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6',
+ pragma: 'no-cache',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-origin',
+ },
+ method: 'GET',
+ referrerPolicy: 'strict-origin-when-cross-origin',
+ mode: 'cors',
+ credentials: 'include',
+ })
+ .then(function (response) {
+ return response.json();
+ })
+ .then((data) => {
+ for (let i = 0; i < data.status.statuses.length; ++i) {
+ if (data.status.statuses[i].id.includes('plugin:reportsDashboards')) {
+ this.setState({ isReportingPluginInstalled: true });
+ }
+ }
+ })
+ .catch((error) => {
+ console.log('error is', error);
+ });
+ }
+
+ configureViewParameter(id: string) {
+ this.props.history.replace({
+ ...this.props.location,
+ search: `view=${id}`,
+ });
+ }
+
+ componentDidMount() {
+ this.setBreadcrumbs('');
+ this.loadNotebook();
+ this.checkIfReportingPluginIsInstalled();
+ const searchParams = queryString.parse(this.props.location.search);
+ const view = searchParams['view'];
+ if (!view) {
+ this.configureViewParameter('view_both');
+ }
+ if (view === 'output_only') {
+ this.setState({ selectedViewId: 'output_only' });
+ } else if (view === 'input_only') {
+ this.setState({ selectedViewId: 'input_only' });
+ }
+ }
+
+ render() {
+ const createdText = (
+
+
+ Created {moment(this.state.dateCreated).format(UI_DATE_FORMAT)}
+
+
+ );
+ const viewOptions: EuiButtonGroupOption[] = [
+ {
+ id: 'view_both',
+ label: 'View both',
+ },
+ {
+ id: 'input_only',
+ label: 'Input only',
+ },
+ {
+ id: 'output_only',
+ label: 'Output only',
+ },
+ ];
+ const addParaPanels: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Type',
+ items: [
+ {
+ name: 'Code block',
+ onClick: () => {
+ this.setState({ isAddParaPopoverOpen: false });
+ this.addPara(this.state.paragraphs.length, '', 'CODE');
+ },
+ },
+ {
+ name: 'Visualization',
+ onClick: () => {
+ this.setState({ isAddParaPopoverOpen: false });
+ this.addPara(this.state.paragraphs.length, '', 'VISUALIZATION');
+ },
+ },
+ ],
+ },
+ ];
+ const paraActionsPanels: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Actions',
+ items: [
+ {
+ name: 'Add paragraph to top',
+ panel: 1,
+ },
+ {
+ name: 'Add paragraph to bottom',
+ panel: 2,
+ },
+ {
+ name: 'Run all paragraphs',
+ disabled: this.state.parsedPara.length === 0,
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.runForAllParagraphs((para: ParaType, index: number) => {
+ return para.paraRef.current?.runParagraph();
+ });
+ if (this.state.selectedViewId === 'input_only') {
+ this.updateView('view_both');
+ }
+ },
+ },
+ {
+ name: 'Clear all outputs',
+ disabled: this.state.parsedPara.length === 0,
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.showClearOutputsModal();
+ },
+ },
+ {
+ name: 'Delete all paragraphs',
+ disabled: this.state.parsedPara.length === 0,
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.showDeleteAllParaModal();
+ },
+ },
+ ],
+ },
+ {
+ id: 1,
+ title: 'Add to top',
+ items: [
+ {
+ name: 'Code block',
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.addPara(0, '', 'CODE');
+ },
+ },
+ {
+ name: 'Visualization',
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.addPara(0, '', 'VISUALIZATION');
+ },
+ },
+ ],
+ },
+ {
+ id: 2,
+ title: 'Add to bottom',
+ items: [
+ {
+ name: 'Code block',
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.addPara(this.state.paragraphs.length, '', 'CODE');
+ },
+ },
+ {
+ name: 'Visualization',
+ onClick: () => {
+ this.setState({ isParaActionsPopoverOpen: false });
+ this.addPara(this.state.paragraphs.length, '', 'VISUALIZATION');
+ },
+ },
+ ],
+ },
+ ];
+ const noteActionsPanels: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Notebook actions',
+ items: [
+ {
+ name: 'Rename notebook',
+ onClick: () => {
+ this.setState({ isNoteActionsPopoverOpen: false });
+ this.showRenameModal();
+ },
+ },
+ {
+ name: 'Duplicate notebook',
+ onClick: () => {
+ this.setState({ isNoteActionsPopoverOpen: false });
+ this.showCloneModal();
+ },
+ },
+ {
+ name: 'Delete notebook',
+ onClick: () => {
+ this.setState({ isNoteActionsPopoverOpen: false });
+ this.showDeleteNotebookModal();
+ },
+ },
+ ],
+ },
+ ];
+
+ const reportingActionPanels: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Reporting',
+ items: [
+ {
+ name: 'Download PDF',
+ icon: ,
+ onClick: () => {
+ this.setState({ isReportingActionsPopoverOpen: false });
+ generateInContextReport('pdf', this.props, this.toggleReportingLoadingModal);
+ },
+ },
+ {
+ name: 'Download PNG',
+ icon: ,
+ onClick: () => {
+ this.setState({ isReportingActionsPopoverOpen: false });
+ generateInContextReport('png', this.props, this.toggleReportingLoadingModal);
+ },
+ },
+ {
+ name: 'Create report definition',
+ icon: ,
+ onClick: () => {
+ this.setState({ isReportingActionsPopoverOpen: false });
+ contextMenuCreateReportDefinition(window.location.href);
+ },
+ },
+ {
+ name: 'View reports',
+ icon: ,
+ onClick: () => {
+ this.setState({ isReportingActionsPopoverOpen: false });
+ contextMenuViewReports();
+ },
+ },
+ ],
+ },
+ ];
+
+ const showReportingContextMenu = this.state.isReportingPluginInstalled ? (
+
+ this.setState({ isReportingActionsPopoverOpen: true })}
+ >
+ Reporting actions
+
+ }
+ isOpen={this.state.isReportingActionsPopoverOpen}
+ closePopover={() => this.setState({ isReportingActionsPopoverOpen: false })}
+ >
+
+
+
+ ) : null;
+
+ const showLoadingModal = this.state.isReportingLoadingModalOpen ? (
+
+ ) : null;
+
+ return (
+
+
+
+
+
+ {this.state.parsedPara.length > 0 && (
+
+ {
+ this.updateView(id);
+ }}
+ />
+
+ )}
+
+
+
+ this.setState({ isParaActionsPopoverOpen: true })}
+ >
+ Paragraph actions
+
+ }
+ isOpen={this.state.isParaActionsPopoverOpen}
+ closePopover={() => this.setState({ isParaActionsPopoverOpen: false })}
+ >
+
+
+
+ {showReportingContextMenu}
+
+ this.setState({ isNoteActionsPopoverOpen: true })}
+ >
+ Notebook actions
+
+ }
+ isOpen={this.state.isNoteActionsPopoverOpen}
+ closePopover={() => this.setState({ isNoteActionsPopoverOpen: false })}
+ >
+
+
+
+
+
+
+ {this.state.path}
+
+
+
+
+ {createdText}
+
+
+ {this.state.parsedPara.length > 0 ? (
+ <>
+ {this.state.parsedPara.map((para: ParaType, index: number) => (
+
+
this.setPara(para, index)}
+ dateModified={this.state.paragraphs[index]?.dateModified}
+ index={index}
+ paraCount={this.state.parsedPara.length}
+ paragraphSelector={this.paragraphSelector}
+ textValueEditor={this.textValueEditor}
+ handleKeyPress={this.handleKeyPress}
+ addPara={this.addPara}
+ DashboardContainerByValueRenderer={
+ this.props.DashboardContainerByValueRenderer
+ }
+ deleteVizualization={this.deleteVizualization}
+ http={this.props.http}
+ selectedViewId={this.state.selectedViewId}
+ setSelectedViewId={this.updateView}
+ deletePara={this.showDeleteParaModal}
+ runPara={this.updateRunParagraph}
+ clonePara={this.cloneParaButton}
+ movePara={this.movePara}
+ showQueryParagraphError={this.state.showQueryParagraphError}
+ queryParagraphErrorMessage={this.state.queryParagraphErrorMessage}
+ />
+
+ ))}
+ {this.state.selectedViewId !== 'output_only' && (
+ <>
+
+ this.setState({ isAddParaPopoverOpen: true })}
+ >
+ Add paragraph
+
+ }
+ isOpen={this.state.isAddParaPopoverOpen}
+ closePopover={() => this.setState({ isAddParaPopoverOpen: false })}
+ >
+
+
+ >
+ )}
+ >
+ ) : (
+ // show default paragraph if no paragraphs in this notebook
+
+
+
+
+ No paragraphs
+
+ Add a paragraph to compose your document or story. Notebooks now support two
+ types of input:
+
+
+
+
+
+
+ }
+ title="Code block"
+ description="Write contents directly using markdown, SQL or PPL."
+ footer={
+ this.addPara(0, '', 'CODE')}
+ style={{ marginBottom: 17 }}
+ >
+ Add code block
+
+ }
+ />
+
+
+ }
+ title="Visualization"
+ description="Import OpenSearch Dashboards or Observability visualizations to the notes."
+ footer={
+ this.addPara(0, '', 'VISUALIZATION')}
+ style={{ marginBottom: 17 }}
+ >
+ Add visualization
+
+ }
+ />
+
+
+
+
+
+
+ )}
+ {showLoadingModal}
+
+
+ {this.state.isModalVisible && this.state.modalLayout}
+
+ );
+ }
+}
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_input.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_input.test.tsx.snap
new file mode 100644
index 000000000..4f8523b7d
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_input.test.tsx.snap
@@ -0,0 +1,318 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the markdown component 1`] = `
+
+
+
+
+
+
+ # Type your input here
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[` spec renders the visualization component 1`] = `
+
+
+
+
+
+
+
+
+ Browse
+
+
+
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_output.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_output.test.tsx.snap
new file mode 100644
index 000000000..a4bc6e0ec
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_output.test.tsx.snap
@@ -0,0 +1,82 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders markdown outputs 1`] = `
+
+
+
+ Type your input here
+
+
+
+`;
+
+exports[` spec renders other types of outputs 1`] = `
+
+`;
+
+exports[` spec renders query outputs 1`] = `
+
+
+
+ select * from opensearch_dashboards_sample_data_flights limit 2
+
+
+
+
+
+`;
+
+exports[` spec renders visualization outputs 1`] = `
+
+ 2020-07-21T18:37:44+00:00 - 2020-08-20T18:37:44+00:00
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_query_grid.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_query_grid.test.tsx.snap
new file mode 100644
index 000000000..4f60d0e6f
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/para_query_grid.test.tsx.snap
@@ -0,0 +1,37 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/paragraphs.test.tsx.snap b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/paragraphs.test.tsx.snap
new file mode 100644
index 000000000..ab01c3c85
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/__snapshots__/paragraphs.test.tsx.snap
@@ -0,0 +1,258 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` spec renders the component 1`] = `
+
+
+
+
+ [1] Code block
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+ Last successful run Invalid date.
+
+
+
+
+
+
+
+
+
+
+ Type your input here
+
+
+
+
+
+
+`;
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_input.test.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_input.test.tsx
new file mode 100644
index 000000000..de07ab37d
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_input.test.tsx
@@ -0,0 +1,160 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render, waitFor } from '@testing-library/react';
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { sampleParsedParagraghs1 } from '../../helpers/__tests__/sampleDefaultNotebooks';
+import { ParaInput } from '../para_input';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+ const visOptions1 = Array.from({ length: 5 }, (v, k) => ({
+ label: `visualization-${k}`,
+ key: `key-${k}`,
+ }));
+ const visOptions2 = Array.from({ length: 5 }, (v, k) => ({
+ label: `visualization-${k}`,
+ key: `key-${k}`,
+ }));
+ const visOptions = [
+ { label: 'VisOptions1', options: visOptions1 },
+ { label: 'VisOptions2', options: visOptions2 },
+ ];
+
+ it('renders the markdown component', () => {
+ const para = sampleParsedParagraghs1[0];
+ const textValueEditor = jest.fn();
+ const handleKeyPress = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsOutputStale = jest.fn();
+ const setSelectedVisOption = jest.fn();
+ const setVisType = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('renders the visualization component', () => {
+ const para = sampleParsedParagraghs1[2];
+ const textValueEditor = jest.fn();
+ const handleKeyPress = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsOutputStale = jest.fn();
+ const setSelectedVisOption = jest.fn();
+ const setVisType = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('types in the markdown component', () => {
+ const para = sampleParsedParagraghs1[0];
+ para.isSelected = true;
+ const textValueEditor = jest.fn();
+ const handleKeyPress = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsOutputStale = jest.fn();
+ const setSelectedVisOption = jest.fn();
+ const setVisType = jest.fn();
+ const utils = render(
+
+ );
+ const textarea = utils.container.querySelectorAll('textarea#editorArea')[0];
+ fireEvent.change(textarea, { target: { value: 'test input' } });
+ expect(setIsOutputStale).toBeCalledWith(true);
+ });
+
+ it('clicks the visualization component', async () => {
+ const para = sampleParsedParagraghs1[2];
+ para.isSelected = true;
+ const textValueEditor = jest.fn();
+ const handleKeyPress = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const setIsOutputStale = jest.fn();
+ const setSelectedVisOption = jest.fn();
+ const setVisType = jest.fn();
+ const utils = render(
+
+ );
+ const datepicker = utils.container.querySelectorAll(
+ 'button[data-test-subj="superDatePickerstartDatePopoverButton"]'
+ );
+ fireEvent.click(datepicker[0]);
+
+ utils.getByTestId('para-input-visualization-browse-button').click();
+ await waitFor(() => {
+ // modal should show up
+ utils.getByTestId('para-input-select-button').click();
+ });
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_output.test.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_output.test.tsx
new file mode 100644
index 000000000..167daf25a
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_output.test.tsx
@@ -0,0 +1,83 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { sampleParsedParagraghs1 } from '../../helpers/__tests__/sampleDefaultNotebooks';
+import { ParaOutput } from '../para_output';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders markdown outputs', () => {
+ const para = sampleParsedParagraghs1[0];
+ para.isSelected = true;
+ const setVisInput = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('renders query outputs', () => {
+ const para = sampleParsedParagraghs1[3];
+ para.isSelected = true;
+ const setVisInput = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('renders visualization outputs', () => {
+ const para = sampleParsedParagraghs1[2];
+ para.isSelected = true;
+ const setVisInput = jest.fn();
+ const utils = render(
+ null}
+ />
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+
+ it('renders other types of outputs', () => {
+ const para = sampleParsedParagraghs1[0];
+ para.isSelected = true;
+ para.typeOut = ['HTML', 'TABLE', 'IMG', 'UNKNOWN', undefined];
+ para.out = ['', '', '', '', ''];
+ const setVisInput = jest.fn();
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_query_grid.test.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_query_grid.test.tsx
new file mode 100644
index 000000000..6a59f8e6c
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/para_query_grid.test.tsx
@@ -0,0 +1,46 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { render } from '@testing-library/react';
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { QueryDataGridMemo } from '../para_query_grid';
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the component', () => {
+ const props = {
+ rowCount: 5,
+ queryColumns: [
+ {
+ id: 'bytes',
+ displayAsText: 'bytes',
+ },
+ ],
+ visibleColumns: ['bytes'],
+ dataValues: [
+ {
+ bytes: 6219,
+ },
+ {
+ bytes: 6850,
+ },
+ {
+ bytes: 0,
+ },
+ {
+ bytes: 14113,
+ },
+ {
+ bytes: 2492,
+ },
+ ],
+ };
+ const utils = render( );
+ expect(utils.container.firstChild).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/paragraphs.test.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/paragraphs.test.tsx
new file mode 100644
index 000000000..26a8e2c0a
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/__tests__/paragraphs.test.tsx
@@ -0,0 +1,73 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { fireEvent, render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import httpClientMock from '../../../../../../test/__mocks__/httpClientMock';
+import { sampleParsedParagraghs1 } from '../../helpers/__tests__/sampleDefaultNotebooks';
+import { Paragraphs } from '../paragraphs';
+
+jest.mock('../../../../../../../../src/plugins/embeddable/public', () => ({
+ ViewMode: {
+ EDIT: 'edit',
+ VIEW: 'view',
+ },
+}));
+
+describe(' spec', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders the component', () => {
+ const setPara = jest.fn();
+ const paragraphSelector = jest.fn();
+ const textValueEditor = jest.fn();
+ const handleKeyPress = jest.fn();
+ const addPara = jest.fn();
+ const DashboardContainerByValueRenderer = jest.fn();
+ const deleteVizualization = jest.fn();
+ const setSelectedViewId = jest.fn();
+ const deletePara = jest.fn();
+ const runPara = jest.fn();
+ const clonePara = jest.fn();
+ const movePara = jest.fn();
+ const para = sampleParsedParagraghs1[0];
+ para.isInputExpanded = true;
+ const utils = render(
+
+ );
+ expect(utils.container.firstChild).toMatchSnapshot();
+
+ utils.getByLabelText('Open paragraph menu').click()
+ utils.getByText('Run input').click()
+ utils.getByLabelText('Open paragraph menu').click()
+ utils.getByText('Duplicate').click()
+ utils.getByLabelText('Open paragraph menu').click()
+ utils.getByText('Delete').click()
+ });
+});
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/para_input.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_input.tsx
new file mode 100644
index 000000000..5cc41ddd0
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_input.tsx
@@ -0,0 +1,241 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiButtonEmpty,
+ EuiCodeBlock,
+ EuiComboBox,
+ EuiComboBoxOptionOption,
+ EuiSelectableOption,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFormRow,
+ EuiHighlight,
+ EuiLink,
+ EuiModal,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+ EuiOverlayMask,
+ EuiSelectable,
+ EuiSpacer,
+ EuiSuperDatePicker,
+ EuiText,
+ EuiTextArea,
+} from '@elastic/eui';
+import { Input, Prompt } from '@nteract/presentational-components';
+import { uiSettingsService } from '../../../../../common/utils';
+import React, { useState } from 'react';
+import { ParaType } from '../../../../../common/types/notebooks';
+
+/*
+ * "ParaInput" component is used by notebook to populate paragraph inputs for an open notebook.
+ *
+ * Props taken in as params are:
+ * para - parsed paragraph from notebook
+ * index - index of paragraph in the notebook
+ * textValueEditor - function for handling input in textarea
+ * handleKeyPress - function for handling key press like "Shift-key+Enter" to run paragraph
+ *
+ * Input component of nteract used as a container for notebook UI.
+ * https://components.nteract.io/#input
+ */
+
+export const ParaInput = (props: {
+ para: ParaType;
+ index: number;
+ runParaError: boolean;
+ textValueEditor: (evt: React.ChangeEvent, index: number) => void;
+ handleKeyPress: (evt: React.KeyboardEvent, para: any, index: number) => void;
+ startTime: string;
+ setStartTime: (startTime: string) => void;
+ endTime: string;
+ setEndTime: (endTime: string) => void;
+ setIsOutputStale: (isStale?: boolean) => void;
+ visOptions: EuiComboBoxOptionOption[];
+ selectedVisOption: EuiComboBoxOptionOption[];
+ setSelectedVisOption: (newOption: EuiComboBoxOptionOption[]) => void;
+ setVisType: React.Dispatch>;
+}) => {
+ const { para, index, runParaError, textValueEditor, handleKeyPress } = props;
+
+ const inputPlaceholderString =
+ 'Type %md, %sql or %ppl on the first line to define the input type. \nCode block starts here.';
+
+ const renderParaInput = () => {
+ return (
+
+ {/* If the para is selected show the editor else display the code in the paragraph */}
+ {para.isSelected ? (
+ {
+ textValueEditor(evt, index);
+ props.setIsOutputStale(true);
+ }}
+ onKeyPress={(evt) => handleKeyPress(evt, para, index)}
+ value={para.inp}
+ autoFocus
+ />
+ ) : (
+
+ {para.inp}
+
+ )}
+
+ );
+ };
+
+ const renderVisInput = () => {
+ const [isModalOpen, setIsModalOpen] = useState(false);
+ const [selectableOptions, setSelectableOptions] = useState([]);
+ const [selectableError, setSelectableError] = useState(false);
+
+ const onSelect = () => {
+ const selectedOptions = selectableOptions.filter((opt) => opt.checked === 'on');
+ if (selectedOptions.length === 0) {
+ setSelectableError(true);
+ return;
+ }
+ props.setIsOutputStale(true);
+ if (selectedOptions.length > 0) props.setVisType(selectedOptions[0].className);
+ props.setSelectedVisOption(selectedOptions);
+ setIsModalOpen(false);
+ };
+
+ const renderOption = (option: EuiComboBoxOptionOption, searchValue: string) => {
+ let visURL = `visualize#/edit/${option.key}?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:'${props.startTime}',to:'${props.endTime}'))`;
+ if (option.className === 'OBSERVABILITY_VISUALIZATION') {
+ visURL = `#/event_analytics/explorer/${option.key}`;
+ }
+ return (
+
+ {option.label}
+
+ );
+ };
+
+ return (
+ <>
+
+
+
+ {
+ if (newOption.length > 0) props.setVisType(newOption[0].className);
+ props.setSelectedVisOption(newOption);
+ props.setIsOutputStale(true);
+ }}
+ />
+
+
+
+ {
+ setSelectableOptions([
+ ...props.visOptions[0].options,
+ ...props.visOptions[1].options,
+ ]);
+ setSelectableError(false);
+ setIsModalOpen(true);
+ }}
+ >
+ Browse
+
+
+
+
+
+ {
+ props.setStartTime(e.start);
+ props.setEndTime(e.end);
+ props.setIsOutputStale(true);
+ }}
+ />
+
+
+
+
+
+ {isModalOpen && (
+
+ setIsModalOpen(false)} style={{ width: 500 }}>
+
+ Browse visualizations
+
+
+
+ {
+ setSelectableOptions(newOptions);
+ setSelectableError(false);
+ }}
+ >
+ {(list, search) => (
+ <>
+ {search}
+ {list}
+ >
+ )}
+
+ {selectableError && (
+ <>
+
+
+ {'Visualization is required.'}
+
+ >
+ )}
+
+
+
+ setIsModalOpen(false)}>Cancel
+ onSelect()}
+ fill
+ >
+ Select
+
+
+
+
+ )}
+ >
+ );
+ };
+
+ return (
+
+
+ {para.isVizualisation ? renderVisInput() : renderParaInput()}
+
+ );
+};
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/para_output.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_output.tsx
new file mode 100644
index 000000000..0a3776e9f
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_output.tsx
@@ -0,0 +1,189 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiCodeBlock, EuiSpacer, EuiText } from '@elastic/eui';
+import MarkdownRender from '@nteract/markdown';
+import { Media } from '@nteract/outputs';
+import moment from 'moment';
+import { VisualizationContainer } from '../../../../components/custom_panels/panel_modules/visualization_container';
+import PPLService from '../../../../services/requests/ppl';
+import React, { useState } from 'react';
+import { CoreStart } from '../../../../../../../src/core/public';
+import {
+ DashboardContainerInput,
+ DashboardStart,
+} from '../../../../../../../src/plugins/dashboard/public';
+import { ParaType } from '../../../../../common/types/notebooks';
+import { uiSettingsService } from '../../../../../common/utils';
+import { QueryDataGridMemo } from './para_query_grid';
+
+/*
+ * "ParaOutput" component is used by notebook to populate paragraph outputs for an open notebook.
+ *
+ * Props taken in as params are:
+ * para - parsed paragraph from notebook
+ *
+ * Outputs component of nteract used as a container for notebook UI.
+ * https://components.nteract.io/#outputs
+ */
+export const ParaOutput = (props: {
+ http: CoreStart['http'];
+ pplService: PPLService;
+ para: ParaType;
+ visInput: DashboardContainerInput;
+ setVisInput: (input: DashboardContainerInput) => void;
+ DashboardContainerByValueRenderer: DashboardStart['DashboardContainerByValueRenderer'];
+}) => {
+ const createQueryColumns = (jsonColumns: any[]) => {
+ let index = 0;
+ let datagridColumns = [];
+ for (index = 0; index < jsonColumns.length; ++index) {
+ const datagridColumnObject = {
+ id: jsonColumns[index].name,
+ displayAsText: jsonColumns[index].name,
+ };
+ datagridColumns.push(datagridColumnObject);
+ }
+ return datagridColumns;
+ };
+
+ const getQueryOutputData = (queryObject: any) => {
+ const data = [];
+ let index = 0;
+ let schemaIndex = 0;
+ for (index = 0; index < queryObject.datarows.length; ++index) {
+ let datarowValue = {};
+ for (schemaIndex = 0; schemaIndex < queryObject.schema.length; ++schemaIndex) {
+ const columnName = queryObject.schema[schemaIndex].name;
+ if (typeof queryObject.datarows[index][schemaIndex] === 'object') {
+ datarowValue[columnName] = JSON.stringify(queryObject.datarows[index][schemaIndex]);
+ } else if (typeof queryObject.datarows[index][schemaIndex] === 'boolean') {
+ datarowValue[columnName] = queryObject.datarows[index][schemaIndex].toString();
+ } else {
+ datarowValue[columnName] = queryObject.datarows[index][schemaIndex];
+ }
+ }
+ data.push(datarowValue);
+ }
+ return data;
+ };
+
+ const outputBody = (key: string, typeOut: string, val: string) => {
+ /* Returns a component to render paragraph outputs using the para.typeOut property
+ * Currently supports HTML, TABLE, IMG
+ * TODO: add table rendering
+ */
+ const dateFormat = uiSettingsService.get('dateFormat');
+
+ if (typeOut !== undefined) {
+ switch (typeOut) {
+ case 'QUERY':
+ const inputQuery = para.inp.substring(4, para.inp.length);
+ const queryObject = JSON.parse(val);
+ if (queryObject.hasOwnProperty('error')) {
+ return {val} ;
+ } else {
+ const columns = createQueryColumns(queryObject.schema);
+ const data = getQueryOutputData(queryObject);
+ const [visibleColumns, setVisibleColumns] = useState(() => columns.map(({ id }) => id));
+ return (
+
+
+ {inputQuery}
+
+
+
+
+ );
+ }
+ case 'MARKDOWN':
+ return (
+
+
+
+ );
+ case 'VISUALIZATION':
+ let from = moment(visInput?.timeRange?.from).format(dateFormat);
+ let to = moment(visInput?.timeRange?.to).format(dateFormat);
+ from = from === 'Invalid date' ? visInput.timeRange.from : from;
+ to = to === 'Invalid date' ? visInput.timeRange.to : to;
+ return (
+ <>
+
+ {`${from} - ${to}`}
+
+
+ >
+ );
+ case 'OBSERVABILITY_VISUALIZATION':
+ let fromObs = moment(visInput?.timeRange?.from).format(dateFormat);
+ let toObs = moment(visInput?.timeRange?.to).format(dateFormat);
+ fromObs = fromObs === 'Invalid date' ? visInput.timeRange.from : fromObs;
+ toObs = toObs === 'Invalid date' ? visInput.timeRange.to : toObs;
+ const onEditClick = (savedVisualizationId: string) => {
+ window.location.assign(`#/event_analytics/explorer/${savedVisualizationId}`);
+ };
+ return (
+ <>
+
+ {`${fromObs} - ${toObs}`}
+
+
+
+
+ >
+ );
+ case 'HTML':
+ return (
+
+
+
+ );
+ case 'TABLE':
+ return {val} ;
+ case 'IMG':
+ return ;
+ default:
+ return {val} ;
+ }
+ } else {
+ console.log('output not supported', typeOut);
+ return ;
+ }
+ };
+
+ const { para, DashboardContainerByValueRenderer, visInput, setVisInput } = props;
+
+ return !para.isOutputHidden ? (
+ <>
+ {para.typeOut.map((typeOut: string, tIdx: number) => {
+ return outputBody(para.uniqueId + '_paraOutputBody', typeOut, para.out[tIdx]);
+ })}
+ >
+ ) : null;
+};
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/para_query_grid.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_query_grid.tsx
new file mode 100644
index 000000000..8b8425278
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/para_query_grid.tsx
@@ -0,0 +1,128 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import $ from 'jquery';
+import {
+ EuiDataGrid,
+ EuiLoadingSpinner,
+ EuiSpacer
+} from '@elastic/eui';
+
+type QueryDataGridProps = {
+ rowCount: number,
+ queryColumns: Array,
+ visibleColumns: Array,
+ setVisibleColumns: (visibleColumns: string[]) => void,
+ dataValues: Array,
+}
+
+type RenderCellValueProps = {
+ rowIndex: number,
+ columnId: string
+}
+
+function QueryDataGrid(props: QueryDataGridProps) {
+ const {
+ rowCount,
+ queryColumns,
+ visibleColumns,
+ setVisibleColumns,
+ dataValues,
+ } = props;
+ const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
+ // ** Sorting config
+ const [sortingColumns, setSortingColumns] = useState([]);
+ const [isVisible, setIsVisible] = useState(false);
+
+ const onSort = useCallback(
+ (sortingColumns) => {
+ setSortingColumns(sortingColumns);
+ },
+ [setSortingColumns]
+ );
+
+ const onChangeItemsPerPage = useCallback(
+ (pageSize) =>
+ setPagination((pagination) => ({
+ ...pagination,
+ pageSize,
+ pageIndex: 0,
+ })),
+ [setPagination]
+ );
+
+ const onChangePage = useCallback(
+ (pageIndex) =>
+ setPagination((pagination) => ({ ...pagination, pageIndex })),
+ [setPagination]
+ );
+
+ const renderCellValue = useMemo(() => {
+ return ({ rowIndex, columnId }: RenderCellValueProps) => {
+ return dataValues.hasOwnProperty(rowIndex)
+ ? dataValues[rowIndex][columnId]
+ : null;
+ };
+ }, []);
+
+ const getUpdatedVisibleColumns = (queryColumns: Array) => {
+ let updatedVisibleColumns = [];
+ for (let index = 0; index < queryColumns.length; ++index) {
+ updatedVisibleColumns.push(queryColumns[index].displayAsText);
+ }
+ return updatedVisibleColumns;
+ }
+
+
+ useEffect(() => {
+ if ($('.euiDataGrid__overflow').is(':visible')) {
+ setIsVisible(true);
+ }
+ setTimeout(() => {
+ if ($('.euiDataGrid__overflow').is(':visible')) {
+ setIsVisible(true);
+ }
+ }, 1000);
+ setVisibleColumns(getUpdatedVisibleColumns(queryColumns));
+ }, []);
+
+ const displayLoadingSpinner = (!isVisible) ? (
+ <>
+
+
+ >
+ ) : null;
+
+ return (
+
+ {displayLoadingSpinner}
+
+
+ )
+}
+
+function queryDataGridPropsAreEqual(prevProps: QueryDataGridProps, nextProps: QueryDataGridProps) {
+ return prevProps.rowCount === nextProps.rowCount
+ && JSON.stringify(prevProps.queryColumns) === JSON.stringify(nextProps.queryColumns)
+ && JSON.stringify(prevProps.visibleColumns) === JSON.stringify(nextProps.visibleColumns)
+ && JSON.stringify(prevProps.dataValues) === JSON.stringify(nextProps.dataValues)
+}
+
+export const QueryDataGridMemo = React.memo(QueryDataGrid, queryDataGridPropsAreEqual);
\ No newline at end of file
diff --git a/dashboards-observability/public/components/notebooks/components/paragraph_components/paragraphs.tsx b/dashboards-observability/public/components/notebooks/components/paragraph_components/paragraphs.tsx
new file mode 100644
index 000000000..7926ef263
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/components/paragraph_components/paragraphs.tsx
@@ -0,0 +1,569 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ EuiButton,
+ EuiButtonIcon,
+ EuiComboBoxOptionOption,
+ EuiContextMenu,
+ EuiContextMenuPanelDescriptor,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiFormRow,
+ EuiHorizontalRule,
+ EuiIcon,
+ EuiLink,
+ EuiPanel,
+ EuiPopover,
+ EuiSpacer,
+ EuiText,
+ htmlIdGenerator,
+} from '@elastic/eui';
+import moment from 'moment';
+import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
+import { CoreStart } from '../../../../../../../src/core/public';
+import {
+ DashboardContainerInput,
+ DashboardStart,
+} from '../../../../../../../src/plugins/dashboard/public';
+import { ViewMode } from '../../../../../../../src/plugins/embeddable/public';
+import { NOTEBOOKS_API_PREFIX } from '../../../../../common/constants/notebooks';
+import {
+ PPL_DOCUMENTATION_URL,
+ SQL_DOCUMENTATION_URL,
+ UI_DATE_FORMAT,
+} from '../../../../../common/constants/shared';
+import { ParaType } from '../../../../../common/types/notebooks';
+import { uiSettingsService } from '../../../../../common/utils';
+import { ParaInput } from './para_input';
+import { ParaOutput } from './para_output';
+import { CUSTOM_PANELS_API_PREFIX } from '../../../../../common/constants/custom_panels';
+import PPLService from '../../../../services/requests/ppl';
+import _ from 'lodash';
+
+/*
+ * "Paragraphs" component is used to render cells of the notebook open and "add para div" between paragraphs
+ *
+ * Props taken in as params are:
+ * para - parsed paragraph from notebook
+ * dateModified - last modified time of paragraph
+ * index - index of paragraph in the notebook
+ * paragraphSelector - function used to select a para on click
+ * textValueEditor - function for handling input in textarea
+ * handleKeyPress - function for handling key press like "Shift-key+Enter" to run paragraph
+ * addPara - function to add a new para onclick - "Add Para" Div
+ * DashboardContainerByValueRenderer - Dashboard container renderer for visualization
+ * deleteVizualization - function to delete a para
+ * http object - for making API requests
+ * selectedViewId - selected view: view_both, input_only, output_only
+ * deletePara - function to delete the selected para
+ * runPara - function to run the selected para
+ * clonePara - function to clone the selected para
+ * clearPara - function to clear output of all the paras
+ * movePara - function to move a paragraph at an index to another index
+ *
+ * Cell component of nteract used as a container for paragraphs in notebook UI.
+ * https://components.nteract.io/#cell
+ */
+type ParagraphProps = {
+ pplService: PPLService;
+ para: ParaType;
+ setPara: (para: ParaType) => void;
+ dateModified: string;
+ index: number;
+ paraCount: number;
+ paragraphSelector: (index: number) => void;
+ textValueEditor: (evt: React.ChangeEvent, index: number) => void;
+ handleKeyPress: (evt: React.KeyboardEvent, para: ParaType, index: number) => void;
+ addPara: (index: number, newParaContent: string, inputType: string) => void;
+ DashboardContainerByValueRenderer: DashboardStart['DashboardContainerByValueRenderer'];
+ deleteVizualization: (uniqueId: string) => void;
+ http: CoreStart['http'];
+ selectedViewId: string;
+ setSelectedViewId: (viewId: string, scrollToIndex?: number) => void;
+ deletePara: (para: ParaType, index: number) => void;
+ runPara: (para: ParaType, index: number, vizObjectInput?: string, paraType?: string) => void;
+ clonePara: (para: ParaType, index: number) => void;
+ movePara: (index: number, targetIndex: number) => void;
+ showQueryParagraphError: boolean;
+ queryParagraphErrorMessage: string;
+};
+
+export const Paragraphs = forwardRef((props: ParagraphProps, ref) => {
+ const {
+ pplService,
+ para,
+ index,
+ paragraphSelector,
+ textValueEditor,
+ handleKeyPress,
+ DashboardContainerByValueRenderer,
+ showQueryParagraphError,
+ queryParagraphErrorMessage,
+ http,
+ } = props;
+
+ const [visOptions, setVisOptions] = useState([]); // options for loading saved visualizations
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+ const [runParaError, setRunParaError] = useState(false);
+ const [selectedVisOption, setSelectedVisOption] = useState([]);
+ const [visInput, setVisInput] = useState(undefined);
+ const [visType, setVisType] = useState('');
+
+ // output is available if it's not cleared and vis paragraph has a selected visualization
+ const isOutputAvailable =
+ (para.out.length > 0 && para.out[0] !== '') ||
+ (para.isVizualisation && para.typeOut.length > 0 && visInput !== undefined);
+
+ useImperativeHandle(ref, () => ({
+ runParagraph() {
+ return onRunPara();
+ },
+ }));
+
+ const fetchVisualizations = async () => {
+ let opt1: EuiComboBoxOptionOption[] = [];
+ let opt2: EuiComboBoxOptionOption[] = [];
+ await http
+ .get(`${NOTEBOOKS_API_PREFIX}/visualizations`)
+ .then((res) => {
+ opt1 = res.savedVisualizations.map((vizObject) => ({
+ label: vizObject.label,
+ key: vizObject.key,
+ className: 'VISUALIZATION',
+ }));
+ })
+ .catch((err) => console.error('Fetching dashboard visualization issue', err.body.message));
+
+ await http
+ .get(`${CUSTOM_PANELS_API_PREFIX}/visualizations`)
+ .then((res) => {
+ const noAppVisualizations = res.visualizations.filter((vis) => {
+ return !!!vis.application_id;
+ });
+ opt2 = noAppVisualizations.map((vizObject) => ({
+ label: vizObject.name,
+ key: vizObject.id,
+ className: 'OBSERVABILITY_VISUALIZATION',
+ }));
+ })
+ .catch((err) =>
+ console.error('Fetching observability visualization issue', err.body.message)
+ );
+
+ const allVisualizations = [
+ { label: 'Dashboards Visualizations', options: opt1 },
+ { label: 'Observability Visualizations', options: opt2 },
+ ];
+ setVisOptions(allVisualizations);
+
+ const selectedObject = _.filter([...opt1, ...opt2], {
+ key: para.visSavedObjId,
+ });
+ if (selectedObject.length > 0) {
+ setVisType(selectedObject.className);
+ setSelectedVisOption(selectedObject);
+ }
+ };
+
+ useEffect(() => {
+ if (para.isVizualisation) {
+ if (para.visSavedObjId !== '') setVisInput(JSON.parse(para.vizObjectInput));
+ fetchVisualizations();
+ }
+ }, []);
+
+ const createDashboardVizObject = (objectId: string) => {
+ const vizUniqueId = htmlIdGenerator()();
+ // a dashboard container object for new visualization
+ const newVizObject: DashboardContainerInput = {
+ viewMode: ViewMode.VIEW,
+ panels: {
+ '1': {
+ gridData: {
+ x: 0,
+ y: 0,
+ w: 50,
+ h: 20,
+ i: '1',
+ },
+ type: 'visualization',
+ explicitInput: {
+ id: '1',
+ savedObjectId: objectId,
+ },
+ },
+ },
+ isFullScreenMode: false,
+ filters: [],
+ useMargins: false,
+ id: vizUniqueId,
+ timeRange: {
+ to: para.visEndTime,
+ from: para.visStartTime,
+ },
+ title: 'embed_viz_' + vizUniqueId,
+ query: {
+ query: '',
+ language: 'lucene',
+ },
+ refreshConfig: {
+ pause: true,
+ value: 15,
+ },
+ };
+ return newVizObject;
+ };
+
+ const onRunPara = () => {
+ if (
+ (!para.isVizualisation && !para.inp) ||
+ (para.isVizualisation && selectedVisOption.length === 0)
+ ) {
+ setRunParaError(true);
+ return;
+ }
+ let newVisObjectInput = undefined;
+ if (para.isVizualisation) {
+ const inputTemp = createDashboardVizObject(selectedVisOption[0].key);
+ setVisInput(inputTemp);
+ setRunParaError(false);
+ newVisObjectInput = JSON.stringify(inputTemp);
+ }
+ setRunParaError(false);
+ return props.runPara(para, index, newVisObjectInput, visType);
+ };
+
+ const setStartTime = (time: string) => {
+ const newPara = props.para;
+ newPara.visStartTime = time;
+ props.setPara(newPara);
+ };
+ const setEndTime = (time: string) => {
+ const newPara = props.para;
+ newPara.visEndTime = time;
+ props.setPara(newPara);
+ };
+ const setIsOutputStale = (isStale: boolean) => {
+ const newPara = props.para;
+ newPara.isOutputStale = isStale;
+ props.setPara(newPara);
+ };
+
+ // do not show output if it is a visualization paragraph and visInput is not loaded yet
+ const paraOutput = (!para.isVizualisation || visInput) && (
+
+ );
+
+ // do not show input and EuiPanel if view mode is output_only
+ if (props.selectedViewId === 'output_only') {
+ return paraOutput;
+ }
+
+ const renderParaHeader = (type: string, index: number) => {
+ const panels: EuiContextMenuPanelDescriptor[] = [
+ {
+ id: 0,
+ title: 'Paragraph actions',
+ items: [
+ {
+ name: 'Insert paragraph above',
+ panel: 1,
+ },
+ {
+ name: 'Insert paragraph below',
+ panel: 2,
+ },
+ {
+ name: 'Run input',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ onRunPara();
+ },
+ },
+ {
+ name: 'Move up',
+ disabled: index === 0,
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.movePara(index, index - 1);
+ },
+ },
+ {
+ name: 'Move to top',
+ disabled: index === 0,
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.movePara(index, 0);
+ },
+ },
+ {
+ name: 'Move down',
+ disabled: index === props.paraCount - 1,
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.movePara(index, index + 1);
+ },
+ },
+ {
+ name: 'Move to bottom',
+ disabled: index === props.paraCount - 1,
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.movePara(index, props.paraCount - 1);
+ },
+ },
+ {
+ name: 'Duplicate',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.clonePara(para, index + 1);
+ },
+ },
+ {
+ name: 'Delete',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.deletePara(para, index);
+ },
+ },
+ ],
+ },
+ {
+ id: 1,
+ title: 'Insert paragraph above',
+ items: [
+ {
+ name: 'Code block',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.addPara(index, '', 'CODE');
+ },
+ },
+ {
+ name: 'Visualization',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.addPara(index, '', 'VISUALIZATION');
+ },
+ },
+ ],
+ },
+ {
+ id: 2,
+ title: 'Insert paragraph below',
+ items: [
+ {
+ name: 'Code block',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.addPara(index + 1, '', 'CODE');
+ },
+ },
+ {
+ name: 'Visualization',
+ onClick: () => {
+ setIsPopoverOpen(false);
+ props.addPara(index + 1, '', 'VISUALIZATION');
+ },
+ },
+ ],
+ },
+ ];
+
+ return (
+ <>
+
+
+
+ {`[${index + 1}] ${type} `}
+ {
+ const newPara = props.para;
+ newPara.isInputExpanded = !newPara.isInputExpanded;
+ props.setPara(newPara);
+ }}
+ />
+
+
+
+ setIsPopoverOpen(true)}
+ />
+ }
+ isOpen={isPopoverOpen}
+ closePopover={() => setIsPopoverOpen(false)}
+ >
+
+
+
+
+
+ >
+ );
+ };
+
+ const renderOutputTimestampMessage = () => {
+ if (props.selectedViewId === 'view_both') {
+ return (
+ <>
+
+
+ {para.isOutputStale ? (
+
+ ) : (
+
+ )}
+
+
+
+ {`Last successful run ${moment(props.dateModified).format(UI_DATE_FORMAT)}.`}
+
+
+ >
+ );
+ } else {
+ // render message when view mode is input_only
+ return (
+ <>
+
+
+
+
+
+
+ {`Output available from ${moment(props.dateModified).format(UI_DATE_FORMAT)}`}
+
+
+
+
+ props.setSelectedViewId('view_both', index)}>
+ View both
+
+
+
+ >
+ );
+ }
+ };
+
+ const sqlIcon = (
+
+ {' '}
+ SQL {' '}
+
+ );
+
+ const pplIcon = (
+
+ {' '}
+ PPL
+
+ );
+
+ const paragraphLabel = !para.isVizualisation ? (
+
+ Specify the input language on the first line using %[language type]. Supported languages
+ include markdown, {sqlIcon} and {pplIcon}.
+
+ ) : null;
+
+ const queryErrorMessage = queryParagraphErrorMessage.includes('SQL') ? (
+
+ {queryParagraphErrorMessage}. Learn More{' '}
+
+
+
+
+ ) : (
+
+ {queryParagraphErrorMessage}.{' '}
+
+ Learn More
+
+
+ );
+
+ const paraClass = `notebooks-paragraph notebooks-paragraph-${
+ uiSettingsService.get('theme:darkMode') ? 'dark' : 'light'
+ }`;
+
+ return (
+ <>
+
+ {renderParaHeader(!para.isVizualisation ? 'Code block' : 'Visualization', index)}
+ paragraphSelector(index)}>
+ {para.isInputExpanded && (
+ <>
+
+
+
+
+ {runParaError && (
+
{`${
+ para.isVizualisation ? 'Visualization' : 'Input'
+ } is required.`}
+ )}
+
+
+
+ onRunPara()} fill>
+ {isOutputAvailable ? 'Refresh' : 'Run'}
+
+
+ {isOutputAvailable && renderOutputTimestampMessage()}
+
+
+ >
+ )}
+ {props.selectedViewId !== 'input_only' && isOutputAvailable && (
+ <>
+
+
+ {paraOutput}
+
+ >
+ )}
+
+
+ >
+ );
+});
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/API_Documentation.md b/dashboards-observability/public/components/notebooks/docs/dev/API_Documentation.md
new file mode 100644
index 000000000..31aec29f6
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/dev/API_Documentation.md
@@ -0,0 +1,706 @@
+# Notebooks API Design Documentation
+
+## Contents
+
+1. [**Notebook Examples**](#notebook-examples)
+2. [**Note APIs**](#notes-apis)
+3. [**Paragraph APIs**](#paragraph-apis)
+4. [**Future Work**](#future-work)
+5. [**References**](#references)
+
+## OpenSearch Dashboards Notebooks REST APIs
+
+**_NOTE:_** The Notebook/Paragraph structure used in body & responses, are with Zeppelin Backend Adaptor. The structure of noteboook and paragraph changes with change in backend, but format of request body and response body remains the same.
+
+## Notebook Examples
+
+- **Default Notebook**
+
+```
+{
+ id: 'note_5f4b9eed-5898-4b39-ba6c-755c0fadd84e',
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ name: 'test 1',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ pluginVersion: '7.9.0',
+ backend: 'Default',
+ paragraphs: [
+ {
+ output: [{ result: '# Type your input here', outputType: 'MARKDOWN', execution_time: '0s' }],
+ input: { inputText: '# Type your input here', inputType: 'MARKDOWN' },
+ dateCreated: '2020-08-20T18:00:59.845Z',
+ dateModified: '2020-08-20T18:00:59.845Z',
+ id: 'paragraph_1a710988-ec19-4caa-83cc-38eb609427d1',
+ },
+ {
+ output: [{ result: '', outputType: 'VISUALIZATION', execution_time: '0s' }],
+ input: {
+ inputText:
+ '{"viewMode":"view","panels":{"1":{"gridData":{"x":1,"y":0,"w":44,"h":20,"i":"1"},"type":"visualization","explicitInput":{"id":"1","savedObjectId":"935afa20-e0cd-11e7-9d07-1398ccfcefa3","vis":null}}},"isFullScreenMode":false,"filters":[],"useMargins":false,"id":"i3ccc6260-e314-11ea-9f99-b37e94bb02ca","timeRange":{"to":"2020-08-20T18:37:44.710Z","from":"2020-07-21T18:37:44.710Z"},"title":"embed_viz_i3ccc6260-e314-11ea-9f99-b37e94bb02ca","query":{"query":"","language":"lucene"},"refreshConfig":{"pause":true,"value":15}}',
+ inputType: 'VISUALIZATION',
+ },
+ dateCreated: '2020-08-20T18:37:44.809Z',
+ dateModified: '2020-08-20T18:37:56.844Z',
+ id: 'paragraph_6d3237a9-6486-4f93-aa25-0a1c838faabd',
+ },
+ ],
+};
+
+```
+
+- **Zeppelin Notebook**
+
+```
+{
+ paragraphs: [
+ {
+ text:
+ "%md\n Input",
+ dateUpdated: '2020-08-20 21:15:04.590',
+ config: {},
+ settings: { params: {}, forms: {} },
+ results: {
+ code: 'SUCCESS',
+ msg: [
+ {
+ type: 'HTML',
+ data:
+ '\nInput
',
+ },
+ ],
+ },
+ apps: [],
+ runtimeInfos: {},
+ progressUpdateIntervalMs: 500,
+ jobName: 'paragraph_1597958104590_901298942',
+ id: 'paragraph_1596519508360_932236116',
+ dateCreated: '2020-08-20 21:15:04.590',
+ status: 'READY',
+ },
+ ],
+ name: 'Embed Vizualization',
+ id: '2FJH8PW8K',
+ defaultInterpreterGroup: 'spark',
+ version: '0.9.0-preview2',
+ noteParams: {},
+ noteForms: {},
+ angularObjects: {},
+ config: { isZeppelinNotebookCronEnable: false },
+ info: {},
+};
+```
+
+## Notes APIs
+
+1. **Fetch all the notebooks available →** returns a list of notebook id and paths
+
+```
+ GET api/notebooks/
+
+ RESPONSE BODY
+ {
+ "data": [
+ {
+ "id": "2FF3GW3H8",
+ "path": "/Embed Viz"
+ },
+ {
+ "id": "2FHEP953H",
+ "path": "/Log Analysis"
+ },
+ {
+ "id": "2FES7PY77",
+ "path": "/Post-mortem Report"
+ },
+ {
+ "id": "2FFAMT6VV",
+ "path": "/test 1"
+ }
+ ]
+ }
+```
+
+2. **Get all paragraphs of a notebook →** returns list of paragraphs
+
+```
+ GET api/notebooks/note/{noteId}
+
+ RESPONSE BODY // list of Paragraphs
+ {
+ "paragraphs": [
+ {
+ "text": "%md\n# This is markdown test",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 8:24:38 AM",
+ "config": {
+ "tableHide": true,
+ "editorSetting": {
+ "language": "markdown",
+ "editOnDblClick": true,
+ "completionSupport": false
+ },
+ "colWidth": 12,
+ "editorMode": "ace/mode/markdown",
+ "fontSize": 9,
+ "editorHide": false,
+ "results": {},
+ "enabled": true
+ },
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [
+ {
+ "type": "HTML",
+ "data": "\n
This is markdown test \n\n"
+ }
+ ]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597133766113_507090317",
+ "id": "paragraph_1597101740623_82179823",
+ "dateCreated": "Aug 11, 2020 8:16:06 AM",
+ "dateStarted": "Aug 11, 2020 8:24:38 AM",
+ "dateFinished": "Aug 11, 2020 8:24:38 AM",
+ "status": "FINISHED"
+ },
+ {
+ "title": "Paragraph inserted",
+ "text": "%md\n# markdown cell number 2 ",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 8:24:32 AM",
+ "config": {},
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [
+ {
+ "type": "HTML",
+ "data": "\n
markdown cell number 2 \n\n"
+ }
+ ]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597134223413_576247989",
+ "id": "paragraph_1597134223413_576247989",
+ "dateCreated": "Aug 11, 2020 8:23:43 AM",
+ "dateStarted": "Aug 11, 2020 8:24:32 AM",
+ "dateFinished": "Aug 11, 2020 8:24:32 AM",
+ "status": "FINISHED"
+ }
+ ]
+ }
+```
+
+3. **Add a Notebook →** returns new notebook id
+
+```
+ POST api/notebooks/note
+
+ REQUEST BODY
+ {"name": "Demo Notebook"} // new name
+
+ RESPONSE BODY
+ {
+ "status": "OK",
+ "message": "",
+ "body": "2FG6FWGY5" //New Notebook ID
+ }
+```
+
+4. **Rename a Notebook →** returns acknowledgement
+
+```
+ PUT api/notebooks/note/rename
+
+ REQUEST BODY
+ {
+ "noteId": "2FG6FWGY5", // notebook id to be renamed
+ "name":"Demo 1", // new name
+ }
+
+ RESPONSE BODY
+ {
+ "status": "OK",
+ "message": ""
+ }
+```
+
+5. **Clone a Notebook →** returns new notebook id
+
+```
+ POST api/notebooks/note/clone
+
+ REQUEST BODY
+ {
+ "noteId": "2FG6FWGY5", // notebook id to be cloned
+ "name":"Demo 1_copy", // new name for cloned notebook
+ }
+
+ RESPONSE BODY
+ {
+ "status": "OK",
+ "message": "",
+ "body": "2FFAG7HAQ"
+ }
+```
+
+6. **Delete a Notebook →** returns acknowledgement
+
+```
+ DELETE api/notebooks/note/{noteid}
+
+ RESPONSE BODY
+ {
+ "status": "OK",
+ "message": ""
+ }
+```
+
+7. **Import a Notebook →** returns new notebooks Id
+
+```
+ POST api/notebooks/note/import
+
+ REQUEST BODY
+ // { noteObj: {notebooks as json} }
+
+ {
+ "noteObj": {
+ "angularObjects": {},
+ "config": {
+ "isZeppelinNotebookCronEnable": false
+ },
+ "defaultInterpreterGroup": "md",
+ "id": "2FH5EF6QF",
+ "info": {},
+ "name": "test 1",
+ "noteForms": {},
+ "noteParams": {},
+ "paragraphs": [{
+ "apps": [],
+ "config": {
+ "colWidth": 12,
+ "editorHide": false,
+ "editorMode": "ace/mode/markdown",
+ "editorSetting": {
+ "completionSupport": false,
+ "editOnDblClick": true,
+ "language": "markdown"
+ },
+ "enabled": true,
+ "fontSize": 9,
+ "results": {},
+ "tableHide": true
+ },
+ "dateCreated": "2020-08-10 23:22:20.623",
+ "dateFinished": "2020-08-11 08:15:21.175",
+ "dateStarted": "2020-08-11 08:15:21.150",
+ "dateUpdated": "2020-08-11 08:15:21.140",
+ "id": "paragraph_1597101740623_82179823",
+ "jobName": "paragraph_1597101740623_82179823",
+ "progressUpdateIntervalMs": 500,
+ "results": {
+ "code": "SUCCESS",
+ "msg": [{
+ "data": "\n
This is markdown test \n\n",
+ "type": "HTML"
+ }]
+ },
+ "runtimeInfos": {},
+ "settings": {
+ "forms": {},
+ "params": {}
+ },
+ "status": "FINISHED",
+ "text": "# This is markdown test",
+ "user": "anonymous"
+ }],
+ "version": "0.9.0-SNAPSHOT"
+ }
+ }
+
+
+ RESPONSE BODY
+ {
+ "status": "OK",
+ "message": "",
+ "body": "2FF38BHBY" //new notebook id
+ }
+```
+
+8. **Export a Notebook →** Returns a notebooks object
+
+```
+ GET api/notebooks/note/export/{noteid}
+
+ RESPONSE BODY // A notebook object
+ {
+ "paragraphs": [
+ {
+ "text": "# This is markdown test",
+ "user": "anonymous",
+ "dateUpdated": "2020-08-11 17:08:24.063",
+ "config": {
+ "tableHide": true,
+ "editorSetting": {
+ "completionSupport": false,
+ "editOnDblClick": true,
+ "language": "markdown"
+ },
+ "colWidth": 12.0,
+ "editorMode": "ace/mode/markdown",
+ "editorHide": false,
+ "fontSize": 9.0,
+ "results": {},
+ "enabled": true
+ },
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [
+ {
+ "type": "HTML",
+ "data": "\n
This is markdown test \n\n"
+ }
+ ]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597165704063_563073184",
+ "id": "paragraph_1597101740623_82179823",
+ "dateCreated": "2020-08-11 17:08:24.063",
+ "status": "READY"
+ }
+ ],
+ "name": "test 1",
+ "id": "2FF38BHBY",
+ "defaultInterpreterGroup": "spark",
+ "version": "0.9.0-SNAPSHOT",
+ "noteParams": {},
+ "noteForms": {},
+ "angularObjects": {},
+ "config": {
+ "isZeppelinNotebookCronEnable": false
+ },
+ "info": {}
+ }
+```
+
+## Paragraph APIs
+
+1. **Update and Run a Paragraph →** returns the updated paragraph
+
+Does the following backend tasks:
+
+ 1. Updates a paragraph (with new input)
+ 2. Runs it
+ 3. Fetches the paragraph (with updated input and executed result output)
+
+```
+ POST api/notebooks/paragraph/update/run
+
+ REQUEST BODY
+ {
+ "noteId": "2FF38BHBY", // notebook id
+ "paragraphId": "paragraph_1597101740623_82179823", // para id
+ "paragraphInput": "%md\n# This is markdown test 2" // para inp
+ }
+
+ RESPONSE BODY
+ {
+ "text": "%md\n# This is markdown test 2",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 5:35:01 PM",
+ "config": {
+ "tableHide": true,
+ "editorSetting": {
+ "completionSupport": false,
+ "editOnDblClick": true,
+ "language": "markdown"
+ },
+ "colWidth": 12,
+ "editorMode": "ace/mode/markdown",
+ "editorHide": false,
+ "fontSize": 9,
+ "results": {},
+ "enabled": true
+ },
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [
+ {
+ "type": "HTML",
+ "data": "\n
This is markdown test 2 \n\n"
+ }
+ ]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597165704063_563073184",
+ "id": "paragraph_1597101740623_82179823",
+ "dateCreated": "Aug 11, 2020 5:08:24 PM",
+ "dateStarted": "Aug 11, 2020 5:35:01 PM",
+ "dateFinished": "Aug 11, 2020 5:35:01 PM",
+ "status": "FINISHED"
+ }
+```
+
+2. **Update a Paragraph →** returns the updated paragraph
+
+Does the following backend tasks:
+
+ 1. Updates a paragraph (with new input)
+ 2. Fetches the paragraph (with updated input and old output)
+
+NOTE: This API call doesn’t execute the paragraph input, should be used to save a partially written code
+
+```
+ PUT api/notebooks/paragraph/
+
+ REQUEST BODY
+ {
+ "noteId": "2FF3GW3H8", // notebook id
+ "paragraphId": "paragraph_1596519508360_932236116", // para id
+ "paragraphInput": "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* I was not present in previous input"
+ // new input
+ }
+
+ RESPONSE BODY
+ {
+ "text": "%md \n\n### Hi Everyone\n* Here's a demo on **OpenSearch Dashboards Notebooks**\n* I was present in previous input",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 5:52:14 PM",
+ "config": {},
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [{
+ "type": "HTML",
+ // old result
+ "data": "\n
Hi Everyone \n
\nHere’s a demo on OpenSearch Dashboards Notebooks \n \n\n
"
+ }]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597104141269_874537409",
+ "id": "paragraph_1596519508360_932236116",
+ "dateCreated": "Aug 11, 2020 12:02:21 AM",
+ "dateStarted": "Aug 11, 2020 5:51:43 PM",
+ "dateFinished": "Aug 11, 2020 5:51:43 PM",
+ "status": "FINISHED"
+ }
+```
+
+3. **Add a new paragraph →** returns newly created paragraph
+
+Does the following backend tasks:
+
+ 1. Adds new a paragraph
+ 2. Fetches the newly created paragraph
+
+```
+ POST api/notebooks/paragraph/
+
+ REQUEST BODY
+ {
+ "noteId": "2FF3GW3H8", // notebook id
+ "paragraphIndex": 1, // index to create a new para
+ "paragraphInput": "%opensearch\n" // input to be provided in the new para
+ "inputType": "CODE" // a paragraph can be of type CODE or VISUALIZATION
+ }
+
+ RESPONSE BODY
+ {
+ "title": "Paragraph inserted",
+ "text": "%opensearch\n",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 5:56:23 PM",
+ "config": {},
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597168583538_1357513873",
+ "id": "paragraph_1597168583538_1357513873",
+ "dateCreated": "Aug 11, 2020 5:56:23 PM",
+ "status": "READY"
+ }
+```
+
+4. **Delete a paragraph →** returns list of paragraphs
+
+```
+ DELETE api/notebooks/paragraph/{noteId}/{paragraphId}
+
+ RESPONSE BODY // list of Paragraphs
+ {
+ "paragraphs": [{
+ "text": "%md\n# This is markdown test 2",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 6:55:07 PM",
+ "config": {
+ "tableHide": true,
+ "editorSetting": {
+ "completionSupport": false,
+ "editOnDblClick": true,
+ "language": "markdown"
+ },
+ "colWidth": 12,
+ "editorMode": "ace/mode/markdown",
+ "editorHide": false,
+ "fontSize": 9,
+ "results": {},
+ "enabled": true
+ },
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "results": {
+ "code": "SUCCESS",
+ "msg": [{
+ "type": "HTML",
+ "data": "\n
This is markdown test 2 \n\n"
+ }]
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597165704063_563073184",
+ "id": "paragraph_1597101740623_82179823",
+ "dateCreated": "Aug 11, 2020 5:08:24 PM",
+ "dateStarted": "Aug 11, 2020 6:55:07 PM",
+ "dateFinished": "Aug 11, 2020 6:55:07 PM",
+ "status": "FINISHED"
+ }, {
+ "title": "Paragraph inserted",
+ "text": "%opensearch\n",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 6:55:07 PM",
+ "config": {},
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597172107715_362327829",
+ "id": "paragraph_1597172107715_362327829",
+ "dateCreated": "Aug 11, 2020 6:55:07 PM",
+ "status": "READY"
+ }]
+ }
+```
+
+5. **Clear outputs of all paragraphs →** returns list of paragraphs (with empty outputs)
+
+```
+ PUT api/notebooks/paragraph/clear
+
+ REQUEST BODY
+ {"noteId":"2FF38BHBY"} // notebook id to clear all paras
+
+ RESPONSE BODY // list of Paragraphs
+ {
+ "paragraphs": [{
+ "text": "%md\n# This is markdown test 2",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 6:55:07 PM",
+ "config": {
+ "tableHide": true,
+ "editorSetting": {
+ "completionSupport": false,
+ "editOnDblClick": true,
+ "language": "markdown"
+ },
+ "colWidth": 12,
+ "editorMode": "ace/mode/markdown",
+ "editorHide": false,
+ "fontSize": 9,
+ "results": {},
+ "enabled": true
+ },
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597165704063_563073184",
+ "id": "paragraph_1597101740623_82179823",
+ "dateCreated": "Aug 11, 2020 5:08:24 PM",
+ "dateStarted": "Aug 11, 2020 6:55:07 PM",
+ "dateFinished": "Aug 11, 2020 6:55:07 PM",
+ "status": "FINISHED"
+ }, {
+ "title": "Paragraph inserted",
+ "text": "%md\n\n# Output is empty\n",
+ "user": "anonymous",
+ "dateUpdated": "Aug 11, 2020 7:17:31 PM",
+ "config": {},
+ "settings": {
+ "params": {},
+ "forms": {}
+ },
+ "apps": [],
+ "runtimeInfos": {},
+ "progressUpdateIntervalMs": 500,
+ "jobName": "paragraph_1597172107715_362327829",
+ "id": "paragraph_1597172107715_362327829",
+ "dateCreated": "Aug 11, 2020 6:55:07 PM",
+ "dateStarted": "Aug 11, 2020 7:17:31 PM",
+ "dateFinished": "Aug 11, 2020 7:17:31 PM",
+ "status": "FINISHED"
+ }]
+ }
+```
+
+## **Future Work**
+
+### **Short Term**
+
+1. **Notes APIs**
+ 1. Run notebook → runs all the paragraphs and returns the updated list of paragraphs
+ 2. Save notebook → updates all the paragraphs and returns the updated list of paragraphs
+2. **Paragraph APIs**
+ 1. Run a paragraph → runs the paragraph with pre-exisiting input code and returns the updated paragraph (with executed result)
+ 2. Refresh a paragraph → runs the paragraph with pre-exisiting input code at certain intervals and returns the updated paragraph (with executed result)
+
+### **Long Term**
+
+1. Checkpoint notebook → saves all the paragraphs and returns acknowledgement
+2. Extend endpoints like refresh, run, save and checkpoint to be asynchronous
+
+## References:
+
+1. Zeppelin APIs : http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/notebook.html
+2. More About Zeppelin: https://zeppelin.apache.org/docs/0.9.0/
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/Build_Documentation.md b/dashboards-observability/public/components/notebooks/docs/dev/Build_Documentation.md
new file mode 100644
index 000000000..9af178571
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/dev/Build_Documentation.md
@@ -0,0 +1,15 @@
+# Build OpenSearch Dashboards Notebooks Plugin
+
+## Setup OpenSearch & OpenSearch Dashboards dev environment and use the plugin with Zeppelin
+
+- Please follow [README.md](../../../../../../DEVELOPER_GUIDE.md) for build instructions.
+
+- **[Optional] If using Zeppelin Backend Adaptor:**
+ - Setup Zeppelin as mentioned in [Apache Zeppelin Setup: Zeppelin Backend Adaptor](./Zeppelin_backend_adaptor.md#apache-zeppelin-setup)
+ - Edit [this line](https://github.com/opensearch-project/dashboards-notebooks/blob/dev/common/index.ts#L19) to `SELECTED_BACKEND = 'ZEPPELIN';`
+ - Edit [this line](https://github.com/opensearch-project/dashboards-notebooks/blob/dev/common/index.ts#L21) for adding Zeppelin endpoint `zeppelinURL = 'http://localhost:8080';`
+- Start OpenSearch Dashboards
+
+- More on [Usage of Plugin](./Usage_Documentation.md)
+
+- Happy Notebooking :)
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/OpenSearch-Dashboards-Notebooks-Design-Proposal.md b/dashboards-observability/public/components/notebooks/docs/dev/OpenSearch-Dashboards-Notebooks-Design-Proposal.md
new file mode 100644
index 000000000..b9bd9050e
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/dev/OpenSearch-Dashboards-Notebooks-Design-Proposal.md
@@ -0,0 +1,278 @@
+# RFC - OpenSearch Dashboards Notebooks
+
+## Contents
+
+1. [Overview](#1-overview)
+2. [Requirements](#2-requirements)
+3. [User Stories](#3-user-stories)
+4. [Design](#4-design)
+5. [Design Details and Implementation](#5-design-details-and-implementation)
+6. [Build & Usage](#6-build--usage)
+7. [Appendix](#7-appendix)
+8. [References](#8-references)
+
+## 1. Overview
+
+### **1.1 Introduction**
+
+OpenSearch Dashboards Notebooks enable data-driven, interactive data analytics and collaborative documents to be created and used as live notes in OpenSearch Dashboards. They allow devops, support specialists, solution and presales specialists, customer success experts and engineers to create and share stories. They facilitate combining visualizations, timelines and text, code and adding annotations. Here are a few OpenSearch Dashboards Notebooks use-cases:
+
+1. Create post-mortem documents
+2. Design runbooks
+3. Build Live infrastructure reports
+4. Foster data driven explorative collaborations
+
+### **1.2 Motivation**
+
+- **Existing Solution:** OpenSearch Dashboards Dashboards offer a solution for a few selected use cases, and are a great tool if you’re focused on monitoring a known set of metrics over time. Current issues include:
+ - Dashboards are static in nature and are not user-friendly to make quick changes in iterations
+ - Dashboards lack context for visualizations
+ - Dashboards do not have multi-timeline support which are needed for post-mortem and cause analysis
+ - Dashboards are restricted to data sources within the OpenSearch environment
+
+* **Our Solution:** OpenSearch Dashboards Notebooks provide:
+ - Familiar notebooks user-interface for faster iterations as live notes
+ - Markdown/Code interpreters for contextual use of data with detailed explanations by allowing a user to combine saved visualizations, text and graphs
+ - Adaptors to embellish existing data in OpenSearch with other reference data sources.
+ - Support multiple timelines to compare and contrast visualizations
+
+### **1.3 Glossary**
+
+1. _Notebooks:_ An interface for on-the-go code writing and execution
+2. _Paragraphs:_ Each notebook consists on multiple paragraphs with allows users to input code or embed a visualization
+3. _Input Cell:_ Each paragraph consists an input cell that contains code for execution in supported interpreters such as markdown, SQL and DSL.
+4. _Output Cell:_ Each paragraph consists an output cell that contains execution result of code or an embeded visualization with its time-range
+5. _Backend Adaptor:_ An add-on to the existing default backend that provides additional interpreters and storage options.
+
+## 2. Requirements
+
+**Functional:**
+
+1. **Notebooks**
+ 1. As a user, I should be able to use OpenSearch Dashboards Notebooks plugin UI for all the interactions
+ 2. As a user, I should be able to View all the notebooks available
+ 3. As a user, I should be able to Create, Edit, Rename, Delete and Clone Notebooks
+ 4. As a user, I should be able to Import and Export Notebooks for collaborative story telling
+2. **Paragraphs**
+ 1. As a user, I should be able to use Create, Edit, Save, Delete and Clone Paragraphs
+ 2. As a user, I should be able to use Toggle all Inputs of paragraphs
+ 3. As a user, I should be able to use Clear and Toggle all Outputs of paragraphs
+3. **Visualizations**
+ 1. As a user, I should be able to embed Saved Visualizations
+ 2. As a user, I should be able to Resize and Delete embedded Visualizations
+ 3. As a user, I should be able to use multiple timelines for different visualizations
+ 4. As a user, I should be able to Inspect Visualization Data
+4. **Default Backend**
+ 1. As a user, I should be able to use Visualizations and Markdown interpreter in Notebooks
+ 2. As a user, I should be able to use SQL and DSL query interpreters in Notebooks
+ 3. As a user, I should be able to store Notebooks as OpenSearch indices
+5. **Backend Adaptors**
+ 1. As a user, I should be able to plug an add-on external backend services (like [Apache Zeppelin](https://zeppelin.apache.org/), [Amazon SageMaker](https://aws.amazon.com/sagemaker/), [Jupyter](https://jupyter.org/)) to the plugin using adaptors
+ 2. As a user, I should be able to use all the interpreters provided by the plugged backend service in addition to those provided by default
+ 3. As a user, I should be able to use the storage adaptors provided by the plugged backend service
+ 4. As a user, I should be able to use external data sources and environments provided by the plugged backend
+
+**Non-functional:**
+
+1. **Default Backend** - As a user, I should be able to use the plugin’s default interpreters without setting up any external backend service
+2. **Backend Adaptors** - As a user, I should be free to create and use external data planes/environments and bring them to OpenSearch Dashboards via supported adaptors
+3. **Security** - As a user, I should be able to view/clone/read/save/edit notebooks adhering to my role settings
+
+## 3. User Stories
+
+**Operations on notebooks**
+
+1. Create: As a user, I should be able to create a notebook.
+2. View: As a user, I should be able to view the notebook.
+3. Save: As a user, I should be able to save the notebook.
+4. Checkpoint: The notebook automatically saves the notebook after every 3 minutes. If the user loads the notebook after the checkpoint is triggered, it will allow load the content till that point.
+5. Save, Autosave: The notebook can saved. After a given time period, the autosave is triggered on the notebook.
+6. Clone: As a user, I should be able to clone the notebook
+7. Rename: As a user, I should be able to rename the notebook
+8. Delete: As a user, I should be able to delete the notebook
+
+**Create, Edit, Delete content in an individual notebook**
+
+1. As a user, I should be able to add paragraphs to a notebook. I should be able to add markdown or code to a paragraph.
+2. Markdown in a paragraph allows adding text and enables the use of titles/headings, images, lists and hyperlinks.
+3. Code can be added in the form of queries, DSL, PPL, SQL etc.
+4. As a user, I should be able to execute the code block or the markup and the output will get reflected in the output cell. The output will display text, images, lists, visualizations/graphs etc.
+5. As a user, I should be able to annotate the output with comments/tags, usernames, time/date etc. using markdown
+6. Time periods: As a user I should be able to set the date/time periods or date/time to the individual output cells. By default, the date/time reflected is global. This is different from the actual timestamp on when the content was edited.
+
+**Share, export and download notebooks**
+
+1. As a creator of notebooks, I should be able to share a OpenSearch Dashboards Notebook with other users so that they can view and/or edit the notebooks as per the privileges and permissions they have.
+2. I should also be able to share the notebook as a pdf via email. I should also be able to download the story as a pdf.
+
+**List of Notebooks**
+
+1. As a user, I should be able to add the notebooks to a list of notebooks. The list of notebooks shows name of the notebook, creator’s details, and last modified dates.
+2. I should be able to view, share and download the individual notebooks in the list of notebooks.
+3. I should be able to view the list of notebooks.
+4. I should be able to filter notebooks based on whether I created or someone else created them and as per dates modified.
+
+## 4. Design
+
+### **4.1 What (Notebooks)**
+
+- Notebooks are browser-based [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) built upon a number of popular open-source libraries
+
+### **4.2 Where (Notebooks Storage)**
+
+- Notebooks are stored as OpenSearch indices in the default backend. If backend adaptors are used by user, the storage is switched to storage options provided by the external backend service.
+- For example: Apache Zeppelin backend service supports files, Git, Amazon S3, mongo and other storage options.
+
+### **4.3 How (Releases)**
+
+- OpenSearch Dashboards Notebooks will be released as a OpenSearch Dashboards plugin shipped with the Open-Distro for OpenSearch solution.
+
+### **4.4 Architecture**
+
+**4.4.1 Version 1:** In this architecture, Backend is tightly coupled with Apache Zeppelin as a backend service to provide interpreters and storage adaptors
+
+![Notebooks Arch_v1](images/Notebooks_v1.png)
+
+- Pros:
+ - Single Backend configuration is easier for development and usage
+ - Zeppelin Backend will provide one stop shop for interpreters, runtime-environments and storage adaptors
+- Cons:
+ - Users will not be free to customize Zeppelin Backend runtime-environment/storage adaptors
+ - Need to develop a new storage adaptor for Zeppelin to store notebooks as OpenSearch indices [POC details](../poc/docs/Zeppelin_OpenSearch_Storage.md)
+ - Difficult to maintain releases, as we have to sync version currency/patches to Zeppelin code repository
+
+**4.4.2 Version 2:** In this architecture, Backends are switchable with two options of Default backend (Markdown, Visualization support) or Apache Zeppelin Backend (25+ interpreter support)
+
+![Notebooks Arch_v1](images/Notebooks_v2.png)
+
+- Pros:
+ - Default Backend configuration is easy to use for any user who wants to stay away from setting up additional environments and interpreters
+ - Apache Zeppelin Backend will provide users the customizability to add new environments and interpreters
+- Cons:
+ - Once a user selects Apache Zeppelin Backend they will not be able to use visualizations to be embedded in notebooks (provided only by default backend)
+
+**4.4.3 Version 3:** In this architecture, Default backend (Markdown, Visualization support) is provided upfront and a user may choose to bring in their own endpoints for adaptors like Apache Zeppelin, Amazon SageMaker or Jupyter
+
+![Notebooks Arch_v1](images/Notebooks_v3.png)
+
+- Pros:
+ - Default Backend configuration is easy to use for any user who wants to stay away from setting up additional environments and interpreters
+ - An Adaptor provides additional functionalities on top of Default Backend, rather than being replacement
+ - Users are free to bring in their backend service with endpoints for interpreter support, runtime-environment and storages
+- Cons:
+ - Need to develop UI as a decoupled service and need to development of multiple parsers as notebook structures change with different backend adaptors
+
+**4.4.4 Decision:** Even though “Version 1” provides good coupling and ease of development, the maintenance and releases are a big issue striking this option out. "Version 2" provides switchable backends which is easy to use but this switching happens at a cost of not supporting a core functionality of visualizations with Zeppelin backend. Finally, we selected "version 3" as it provides user flexibility to bring their own external backend services to connect to OpenSearch Dashboards Notebooks.
+
+## 5. Design Details and Implementation
+
+### **5.1 OpenSearch Dashboards Notebooks Plugin UI**
+
+1. **React based UI**, uses elements from [OpenSearch UI](https://elastic.github.io/eui/#/) elements & [Nteract.io components](https://components.nteract.io/)
+2. **OpenSearch UI Components**
+ 1. Used for blending notebooks in OpenSearch Dashboards Plugins environment
+ 2. All container UI components and buttons use OpenSearch UI components
+3. **Nteract Components**
+ 1. [_Presentational-components_](https://components.nteract.io/#section-nteractpresentational-components) module of nteract is used specifically for notebook UI
+ 2. _[Outputs](https://components.nteract.io/#section-nteractoutputs)_ module is used for rendering markdown if backend adaptor doesn't have a markdown interpreter
+4. **Notebook Parsers**
+ 1. Each Backend has a different notebook structure, thus we need a parser to convert these notebooks to a common structure. Based on the selected backend a parser converts paragraphs in notebook to a parsed-Paragraph.
+ 2. Parsed-Paragraphs are used to render components of notebooks.
+ 3. FUTURE: Can shift this module to the backend, need to weigh pros and cons as behavior of APIs will change especially for Import and Export would change drastically
+5. Here’s a sample wireframe
+
+![OpenSearch Dashboards Notebooks UI](images/UI.png)
+
+### **5.2 OpenSearch Dashboards Notebooks Plugin Backend**
+
+1. Uses the Hapi Backend Contianer provided by OpenSearch Dashboards
+2. Provides API routes for connecting UI components to a backend service
+3. **_Router Modules_:**
+ 1. NotebookConnector - routes Notebook CRUD operations
+ 2. ParagraphConnector - routes Paragraph CRUD operations
+4. **_Default Backend_:**
+ 1. Provides markdown interpreter support for notebooks
+ 2. Provides ability to embed saved visualizations using Dashboard Containers
+ 3. FUTURE: provide interpreter support for SQL and DSL queries
+5. **Backend Adaptors**
+ 1. A Backend Adaptor provides an interface to connect external notebook backends
+ 2. An external notebook backend service is connected through a HTTP endpoint
+ 3. Once a backend service is connected all the interpreters, environments and data sources provided by the service are automatically extended in notebooks
+ 4. Uses [Hapi Wreck](https://hapi.dev/module/wreck/) to connect a backend service with a HTTP endpoint
+ 5. Example Adaptor: **Zeppelin Backend Server**
+ ![Zeppelin Server](images/zeppelin_architecture.png)
+ - Open source, provided by [Apache Zeppelin](http://zeppelin.apache.org/)
+ - Provides all communication to and from a notebook & supports 25+ interpreters
+ - Connects via a HTTP endpoint to the Plugin backend
+ - [Interpreter APIs](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/interpreter.html) Get interpreter settings, create/update/restart/delete interpreter setting
+ - [Notebook APIs](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/notebook.html) Create/update/restart/delete noteboooks and paragraphs
+ - Provides inter-paragraph communication capabilities
+ - Can be setup to provide OpenSearch and OpenSearch-SQL interpreters
+ - Can be connected with python environment to use ML/plot libraries
+
+### **5.3 Data Model**
+
+- **Default Backend Notebook Schema:** Each notebook object contains it’s name, unique id, date of creation/modification, OpenSearch Dashboards Notebooks plugin version and an array of paragraphs. The paragraphs contain their unique id, date of creation/modification and input/output cells. An input cell contains a code or text and it’s type (markdown/visualization). Each paragraph contains an array of outputs, this is an array as execution of code can result into multiple outputs like a text with an image. Each output contains the type of output, result value and execution time.
+
+![Default Notebooks](images/Default_Notebooks_Schemav2.png)
+
+### **5.4 WorkFlows**
+
+- **Default Backend -** _View Notebooks:_ View notebooks operation is responsible for loading the sidemenu with folder tree. When user loads the plugin a call is made to the backend server. The default backend fetches all the notebooks from “.notebooks” OpenSearch index and responds with notebook Ids and paths. This response load is then used to populate the folder tree with default parser on UI.
+
+ ![View Notebook](images/default_view_notebook.png)
+
+- **Default Backend -** _Create/Edit/Delete Notebooks_: All the other notebook operations like create/delete/clone/import/export and editing paragraphs in notebooks use this workflow. When a use interacts with these notebook functionalities a backend request is made with payload [like paragraphInput, paragraphId] if necessary. The default backend first searches the “.notebooks” OpenSearch index to get the current state of the notebook. Once fetched/searched, it performs the required operation and then indexes/updates/deletes the notebook. After the successful completion of operations a response is sent back to the UI with either whole or partial notebook information (as required) and parsed by default parser taking the notebook schema into consideration.
+
+ ![View Notebook](images/default_operation_notebook.png)
+
+- **Zeppelin Adaptor -** _All Operations:_ When a user uses the Zeppelin backend adaptor for running notebooks, the backend switches its way of making requests. For any user operation including viewing notebooks in folder tree, a backend request is made by UI. This request may contain any payload [like paragraphInput, paragraphId] if necessary. This payload is reformatted and added with additional options like the user’s Zeppelin HTTP endpoint and request headers. Finally this request is sent to the user’s Zeppelin Server, which does the operation and responds back. The response is sent back to the UI with either whole or partial notebook information (as required) and parsed by Zeppelin parser taking Zeppelin’s notebook schema into consideration.
+
+ ![Zeppelin Notebook](images/zeppelin_notebooks_sequence.png)
+
+### **5.5** [API Design Documentation](API_Documentation.md)
+
+## 6. Build & Usage
+
+### **6.1** [Build Documentation](Build_Documentation.md)
+
+### **6.1** [Usage Documentation](Usage_Documentation.md)
+
+## 7. Appendix
+
+### **7.1** POC: [Embeddable API & Usage](../poc/docs/OpenSearch Dashboards_Embeddable_Documentation.md)
+
+### **7.2** POC: [Zeppelin OpenSearch Storage](../poc/docs/Zeppelin_OpenSearch_Storage.md)
+
+### **7.3** Screenshots:
+
+- **Default Backend**
+
+ - **Markdown Interpreter**
+ ![Markdown](images/Markdown_ss.png)
+ - **Embedding Saved Visualizations**
+ ![Viz](images/vizembed_ss.png)
+ - **Multi-Timeline Support**
+ ![Multi-Timeline Support](images/Multi-timeline_ss.png)
+
+- **Zeppelin Backend Adaptor**
+
+ - **Zeppelin Adaptor in OpenSearch Dashboards Notebooks**:
+ ![Sample UI](images/Zeppelin_ss.png)
+ - **Make requests to OpenSearch Service**:
+ ![OpenSearch service UI](images/opensearch_ss.png)
+ - **Transmit Data between Interpreters**:
+
+ - Use output of an OpenSearch Query as save as a Zeppelin Context in a variable
+ ![OpenSearch Query](images/opensearch_ss_zepcontext.png)
+ - Use the Zeppelin Context vairable and import it in python
+ ![Import Context](images/python_ss.png)
+
+ - **Plot Visualization with Language specific Viz. tools (like Matplotlib)**:
+ ![Matplot Viz.](images/matplot_ss.png)
+
+## 8. References
+
+### **8.1** [More Zeppelin and Backend Adaptor](Zeppelin_backend_adaptor.md)
+
+### **8.2** [Nteract.io](https://nteract.io/) React components: [components.nteract.io](https://components.nteract.io/)
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/Usage_Documentation.md b/dashboards-observability/public/components/notebooks/docs/dev/Usage_Documentation.md
new file mode 100644
index 000000000..c4fc7a3fa
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/dev/Usage_Documentation.md
@@ -0,0 +1,40 @@
+# Using OpenSearch Dashboards Notebooks
+
+## Usage & Interface
+
+![OpenSearch Dashboards Notebooks](./images/dashboards-notebooks.gif)
+
+### 1. Notebook Functionalities
+
+![OpenSearch Dashboards Notebooks](./images/notebook-buttons.png)
+
+- **Create Notebook** - creates a new notebook document
+- **Rename Notebook** - renames the current notebook with new name
+- **Clone Notebook** - clones the current notebook and gives the name
+- **Delete Notebook** - deletes the current notebook
+- **Import Notebook** - imports a notebook json file
+- **Export Notebook** - exports the current notebook as a json file
+
+### 2. Paragraph Functionalities
+
+![OpenSearch Dashboards Notebooks](./images/paragraph-buttons.png)
+NOTE: Please select a paragraph before using these buttons
+
+- **Run Paragraph** - Runs the selected paragraph and saves it
+- **Save Paragraph** - Saves the input of selected paragraph/visualization
+- **Clone Paragraph** - Clones the selected paragraph
+- **Delete Paragraph** - Deletes the selected paragraph
+- **Clear All Paragraph** - Clears the output of all the paragraphs
+- **Hide Inputs** - Hides the input cells of all the paragraphs
+- **Hide Outputs** - Hides the output cells of all the paragraphs
+
+### 3. Miscellaneous
+
+- **Adding a paragraph** - Hover between paragraphs to add a new para/visualization
+- **Editing Visualization Timeline** - Edit timeframes in datepicker to add "from" and "to" time range, then refresh the visualization
+- **Resize Visualizations** - To resize a visualization, unpin the visualization to enter the edit mode, once resized pin the visualization and save it with save button on top
+
+## Import Example Notebooks
+
+- Import sample notebooks from [example_notebooks folder](https://github.com/opensearch-project/dashboards-notebooks/tree/dev) based on your backend
+- A notebook from one backend is incompatible to the other
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/Zeppelin_backend_adaptor.md b/dashboards-observability/public/components/notebooks/docs/dev/Zeppelin_backend_adaptor.md
new file mode 100644
index 000000000..054c1a886
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/dev/Zeppelin_backend_adaptor.md
@@ -0,0 +1,129 @@
+# Zeppelin Backend Adaptor
+
+## Contents
+
+1. [**Zeppelin Backend Service**](#zeppelin-backend-service)
+2. [**Apache Zeppelin Setup**](#apache-zeppelin-setup)
+
+## Zeppelin Backend Service
+
+**Apache Zeppelin** provides several REST APIs for interaction and remote activation of zeppelin functionality. All REST APIs are available starting with the following endpoint `http://[zeppelin-server]:[zeppelin-port]/api`.
+
+![Zeppelin Server](images/zeppelin_architecture.png)
+
+1. **APIs Provided:**
+ 1. **[Server:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/zeppelin_server.html)** Get status, version, Log Level
+ 2. **[Interpreter:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/interpreter.html)** Get interpreter settings, create/update/restart/delete interpreter setting
+ 3. **[Notebook:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/notebook.html)** Create/update/restart/delete note and paragraph ops
+ 4. **[Repository:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/notebook_repository.html)** Get/Update NB repo
+ 5. **[Configuration:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/configuration.html)** Get all [Zeppelin config](http://zeppelin.apache.org/docs/0.9.0/setup/operation/configuration.html) - server port, ssl, S3 bucket, S3.user
+ 6. **[Credential:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/credential.html)** List credentials for all users, create/delete
+ 7. **[Helium:](http://zeppelin.apache.org/docs/0.9.0/usage/rest_api/helium.html)** Contains APIs for all plugin packages (Not needed as of now)
+2. **Security:**
+ 1. By default the APIs are exposed to anonymous user
+ 2. Recommended way to use **access control**: **[Shiro Auth](http://zeppelin.apache.org/docs/0.9.0/setup/security/shiro_authentication.html)**
+ 1. Need to change [**Shiro.ini (Apache link)**](http://shiro.apache.org/configuration.html#ini-sections) in conf directory
+ 2. Ideally should be used with [**Apache KnoxSSO**](https://knox.apache.org/books/knox-0-13-0/dev-guide.html#KnoxSSO+Integration)
+ 3. Also, [Notebooks](http://zeppelin.apache.org/docs/0.9.0/setup/security/notebook_authorization.html) can have access control based on Shiro defined users
+3. **Deployment:**
+ 1. Recommended way is to use stand alone docker
+ 2. Create a **custom docker** with new Shiro & Zeppelin configs and set interpreter config for OpenSearch and OpenSearch-sql.
+ 3. Sample scripts available in `scripts/docker/spark-cluster-managers`
+4. **Storage:**
+ 1. Apache Zeppelin has a pluggable notebook storage mechanism controlled by `zeppelin.notebook.storage` configuration option with multiple implementations.
+ 2. Zeppelin has** built-in S3/github connector**. Just provide credentials in [properties or env-sh](http://zeppelin.apache.org/docs/0.9.0/setup/storage/storage.html#notebook-storage-in-s3)
+ 3. The notebooks are automatically synced by Zeppelin
+
+## **Apache Zeppelin Setup**
+
+- https://zeppelin.apache.org/
+- Web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more.
+- **[Installation Steps](http://zeppelin.apache.org/docs/0.9.0/quickstart/install.html)**
+ - http://zeppelin.apache.org/download.html → Install using Binary package with all interpreters.
+ - Unpack the downloaded tar
+ - To Run the service use `bin/zeppelin-daemon.sh start`
+ - To Stop the service use `bin/zeppelin-daemon.sh stop`
+ - Service starts on port 8080
+ - If on a remote server (like ec2) and want to use server IP to access the notebook:
+ - Make sure your inbound/outbound ports are set correctly on the remote machine
+ - You may want to change the Zeppelin host ip to 0.0.0.0 (or keep it localhost)
+ - To change the host ip use the `zeppelin-site.xml.template` inside “conf/“ directory
+ - `cp conf/zeppelin-site.xml.template conf/zeppelin-site.xml`
+ - `vi conf/zeppelin-site.xml` and edit the host ip
+ - Then restart the service
+- **[Optional] Setup OpenSearch Interpreter:**
+
+ - [Zeppelin OpenSearch interpreter Documentation](https://zeppelin.apache.org/docs/0.9.0/interpreter/elasticsearch.html)
+ - This interpreter can be used for OpenSearch:
+
+ - **Note: current issues with OpenSearch Interpreter in Zeppelin**
+ - User needs to remove ssl flag from the OpenSearch config as Zeppelin doesn’t support ssl request yet: https://issues.apache.org/jira/browse/ZEPPELIN-2031 so run the OpenSearch service without ssl enabled
+ - Zeppelin has “no support for ssl” (only uses http) in elastic interpreter:
+ - [Code](https://github.com/apache/zeppelin/blob/0b8423c62ae52f3716d4bb63d60762fee6910788/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java#L105)
+ - [Apache Issues](https://issues.apache.org/jira/browse/ZEPPELIN-2031)
+ - Zeppelin has “no issue in search query” in elastic interpreter:
+ - [Apache Issues](https://issues.apache.org/jira/browse/ZEPPELIN-4843?jql=project%20%3D%20ZEPPELIN%20AND%20status%20%3D%20Open%20AND%20text%20~%20%22elasticsearch%22)
+ - Zeppelin “No support for search template“ issue in elastic interpreter:
+ - [Apache Issues](https://issues.apache.org/jira/browse/ZEPPELIN-4184?jql=project%20%3D%20ZEPPELIN%20AND%20text%20~%20%22elastic%20search%22)
+ - **To Change the interpreter settings of Elastic Search Interpreter on Zeppelin:**
+ - Open Zeppelin in browser `localhost:8080`
+ - Please click the top right menu beside drop down and select interpreter option
+ - In the interpreters window, search for elasticsearch interpreter
+ - Edit config parameters similar to that your local/remote service
+ - You’ll be prompted to restart the interpreter -> Click on ok
+ - **If using the default settings, add below mentioned changes in interpreter config:**
+
+ - Change transport.type to http
+ - host → localhost (if running on same machine as Zeppelin) & port → 9200
+ - username: admin & password: admin
+ - Once configured the screen should look like this:
+ ![OpenSearch Interpreter](images/opensearch-zeppelin.png)
+
+ - Start a new notebook to try out the below commands
+ - Run a shell command from notebook to check availability of OpenSearch:
+ - `%sh curl -XGET http://localhost:9200 -u admin:admin`
+
+```
+%elasticsearch
+index movies/default/1 {
+ "title": "The Godfather",
+ "director": "Francis Ford Coppola",
+ "year": 1972,
+ "genres": ["Crime", "Drama"],
+ "rating":5
+}
+```
+
+- **[Optional] Setup OpenSearch-SQL JDBC Interpreter:**
+ - [Zeppelin JDBC Interpreter Documentation](https://zeppelin.apache.org/docs/0.9.0/interpreter/jdbc.html)
+ - Zeppelin has a generic JDBC interpreter, we can use this to add our OpenSearch-SQL Driver
+ - Download [OpenSearch-SQL Driver](https://opensearch.org/) Jar file
+ - To Use JDBC interpreter:
+ - **To add the JDBC interpreter settings for OpenSearch-SQL:**
+ - Open Zeppelin in browser `localhost:8080`
+ - Please click the top right menu beside drop down and select interpreter option
+ - Click on "+ Create" Button
+ - Add OpenSearch-SQL interpreter with type JDBC **configure name: “opensearchsql”**
+ - Note: The name you assign to the interpreter is used later for accessing paragraphs in notebook - “%opensearchsql”
+ - Edit config for with OpenSearch-SQL Driver details (Please refer to the [Github README](https://github.com/opensearch-project/sql/tree/main/sql-jdbc))
+ - **If using the default settings, add below mentioned changes in interpreter config:**
+ - Edit the url: `jdbc:elasticsearch://localhost:9200`
+ - Edit the driver class: `org.opensearch.jdbc.Driver`
+ - Edit the username to admin
+ - Edit the password to admin
+ - Add absolute path to the Jar in the last input box
+ - You’ll be prompted to restart the interpreter -> Click on ok
+ - Once configured the screen should look like this:
+ ![SQL Interpreter](images/opensearch-zeppelin-settings.png)
+
+ - Open a notebook and run below commands to check if interpreter settings are set correctly
+
+```
+%opensearchsql
+SELECT * FROM movies
+```
+
+- **Appendix:**
+ - **[More on Zeppelin UI](http://zeppelin.apache.org/docs/latest/quickstart/explore_ui.html)**
+ - [**More on Zeppelin Config**](http://zeppelin.apache.org/docs/latest/setup/operation/configuration.html)
+ - [**S3-Notebook Storage**](http://zeppelin.apache.org/docs/0.8.2/setup/storage/storage.html#notebook-storage-in-s3)
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Default_Notebooks_Schemav2.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Default_Notebooks_Schemav2.png
new file mode 100644
index 000000000..8a0e2b5ed
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Default_Notebooks_Schemav2.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Embeddable_API.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Embeddable_API.png
new file mode 100644
index 000000000..e24715664
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Embeddable_API.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Markdown_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Markdown_ss.png
new file mode 100644
index 000000000..80c9aa788
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Markdown_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Multi-timeline_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Multi-timeline_ss.png
new file mode 100644
index 000000000..b349d96ca
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Multi-timeline_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v1.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v1.png
new file mode 100644
index 000000000..9e246ad32
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v1.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v2.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v2.png
new file mode 100644
index 000000000..825c924cc
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v2.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v3.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v3.png
new file mode 100644
index 000000000..752e1b252
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Notebooks_v3.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/UI.png b/dashboards-observability/public/components/notebooks/docs/dev/images/UI.png
new file mode 100644
index 000000000..a8716452a
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/UI.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/Zeppelin_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/Zeppelin_ss.png
new file mode 100644
index 000000000..7efd3c854
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/Zeppelin_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards-notebooks.gif b/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards-notebooks.gif
new file mode 100644
index 000000000..2439e1ab0
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards-notebooks.gif differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards_notebooks_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards_notebooks_ss.png
new file mode 100644
index 000000000..e230c1ed7
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/dashboards_notebooks_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/default_backend_model.png b/dashboards-observability/public/components/notebooks/docs/dev/images/default_backend_model.png
new file mode 100644
index 000000000..954e18f0f
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/default_backend_model.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/default_operation_notebook.png b/dashboards-observability/public/components/notebooks/docs/dev/images/default_operation_notebook.png
new file mode 100644
index 000000000..122765d9a
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/default_operation_notebook.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/default_view_notebook.png b/dashboards-observability/public/components/notebooks/docs/dev/images/default_view_notebook.png
new file mode 100644
index 000000000..631288692
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/default_view_notebook.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/matplot_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/matplot_ss.png
new file mode 100644
index 000000000..91efc0c22
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/matplot_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/notebook-buttons.png b/dashboards-observability/public/components/notebooks/docs/dev/images/notebook-buttons.png
new file mode 100644
index 000000000..30bc67dcd
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/notebook-buttons.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin-settings.png b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin-settings.png
new file mode 100644
index 000000000..ee05b5ced
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin-settings.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin.png b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin.png
new file mode 100644
index 000000000..479be39c2
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch-zeppelin.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss.png
new file mode 100644
index 000000000..fc6317879
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss_zepcontext.png b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss_zepcontext.png
new file mode 100644
index 000000000..5a0ab2b94
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/opensearch_ss_zepcontext.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/paragraph-buttons.png b/dashboards-observability/public/components/notebooks/docs/dev/images/paragraph-buttons.png
new file mode 100644
index 000000000..9b1f159f4
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/paragraph-buttons.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/python_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/python_ss.png
new file mode 100644
index 000000000..297c7ed09
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/python_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/vizembed_ss.png b/dashboards-observability/public/components/notebooks/docs/dev/images/vizembed_ss.png
new file mode 100644
index 000000000..d3c89b471
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/vizembed_ss.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_architecture.png b/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_architecture.png
new file mode 100644
index 000000000..cc1a64e70
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_architecture.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_notebooks_sequence.png b/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_notebooks_sequence.png
new file mode 100644
index 000000000..27d4c5033
Binary files /dev/null and b/dashboards-observability/public/components/notebooks/docs/dev/images/zeppelin_notebooks_sequence.png differ
diff --git a/dashboards-observability/public/components/notebooks/docs/example_notebooks/default/Introduction Notebook.json b/dashboards-observability/public/components/notebooks/docs/example_notebooks/default/Introduction Notebook.json
new file mode 100644
index 000000000..a0667d3c7
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/example_notebooks/default/Introduction Notebook.json
@@ -0,0 +1 @@
+{"id":"note_97f67897-2786-48de-8f89-a3e4ffbf82b7","dateCreated":"2020-08-21T04:14:37.422Z","name":"Introduction Notebook","dateModified":"2020-08-21T04:18:47.576Z","pluginVersion":"7.9.0","backend":"Default","paragraphs":[{"output":[{"result":"## Hi Everyone,\n### Here's an intro to **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to create, rename, clone, delete, import and export with notebooks \n* Inner top left buttons are used to run, save, clone, delete the selected paragraph. \n* Long hover over the buttons to see Tooltip helpers","outputType":"MARKDOWN","execution_time":"0s"}],"input":{"inputText":"## Hi Everyone,\n### Here's an intro to **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to create, rename, clone, delete, import and export with notebooks \n* Inner top left buttons are used to run, save, clone, delete the selected paragraph. \n* Long hover over the buttons to see Tooltip helpers","inputType":"MARKDOWN"},"dateCreated":"2020-08-21T04:14:37.422Z","dateModified":"2020-08-21T04:15:02.395Z","id":"paragraph_51ff08eb-1fac-4198-8988-eba18de27440"},{"output":[{"result":"## Greetings!\n* The notebooks are stored in elasticsearch index\n* Yay! you may import and export me as json files\n* **Run** a paragraph with a keyboard shortcut **\"Shift+Enter\"**\n* The default backend supports **markdown** and **saved visualizations**","outputType":"MARKDOWN","execution_time":"0s"}],"input":{"inputText":"## Greetings!\n* The notebooks are stored in elasticsearch index\n* Yay! you may import and export me as json files\n* **Run** a paragraph with a keyboard shortcut **\"Shift+Enter\"**\n* The default backend supports **markdown** and **saved visualizations**","inputType":"MARKDOWN"},"dateCreated":"2020-08-21T04:15:06.311Z","dateModified":"2020-08-21T04:18:27.636Z","id":"paragraph_bb4e4188-0d9f-44ed-b0ea-e37c4f6293be"},{"output":[{"result":"### Hover between paragraphs to add a Saved Visualization or a New Paragraph\n2. **Unpin** the container to *edit the size* or *delete it*\n3. **Refresh** the container after *date is changed*\n","outputType":"MARKDOWN","execution_time":"0s"}],"input":{"inputText":"### Hover between paragraphs to add a Saved Visualization or a New Paragraph\n2. **Unpin** the container to *edit the size* or *delete it*\n3. **Refresh** the container after *date is changed*\n","inputType":"MARKDOWN"},"dateCreated":"2020-08-21T04:18:31.129Z","dateModified":"2020-08-21T04:18:38.923Z","id":"paragraph_7521a92a-1390-4e12-9b69-75de5878791f"},{"output":[{"result":"# Start typing here","outputType":"MARKDOWN","execution_time":"0s"}],"input":{"inputText":"# Start typing here","inputType":"MARKDOWN"},"dateCreated":"2020-08-21T04:18:45.508Z","dateModified":"2020-08-21T04:18:47.576Z","id":"paragraph_8a1a37a2-f759-4f28-8dfd-0c3210edc23b"}]}
diff --git a/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Introduction Notebook-Zeppelin.json b/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Introduction Notebook-Zeppelin.json
new file mode 100644
index 000000000..90e3c157f
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Introduction Notebook-Zeppelin.json
@@ -0,0 +1 @@
+{"paragraphs":[{"text":"%md \n\n## Hi Everyone,\n### Here's an intro to **OpenSearch Dashboards Notebooks**\n* You may use the top left buttons to create, rename, clone, delete, import and export with notebooks \n* Inner top left buttons are used to run, save, clone, delete the selected paragraph. \n* Long hover over the buttons to see Tooltip helpers","user":"anonymous","dateUpdated":"2020-08-21 00:55:58.360","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Hi Everyone, \n
Here’s an intro to OpenSearch Dashboards Notebooks \n
\nYou may use the top left buttons to create, rename, clone, delete, import and export with notebooks \nInner top left buttons are used to run, save, clone, delete the selected paragraph. \nLong hover over the buttons to see Tooltip helpers \n \n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958104590_901298942","id":"paragraph_1596519508360_932236116","dateCreated":"2020-08-20 21:15:04.590","dateStarted":"2020-08-21 00:55:58.362","dateFinished":"2020-08-21 00:55:58.368","status":"FINISHED"},{"title":"CODE","text":"%md\n\n## Greetings!\n* Yay! you may import and export me as json files\n* **Run** a paragraph with a keyboard shortcut **\"Shift+Enter\"**\n* In Zeppelin each paragraph has to have a \"%[interpreter]\" header (like %md in this paragraph)","user":"anonymous","dateUpdated":"2020-08-21 01:08:56.942","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Greetings! \n
\nYay! you may import and export me as json files \nRun a paragraph with a keyboard shortcut “Shift+Enter” \nIn Zeppelin each paragraph has to have a “%[interpreter]” header (like %md in this paragraph) \n \n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597972120089_1145163794","id":"paragraph_1597972120089_1145163794","dateCreated":"2020-08-21 01:08:40.089","dateStarted":"2020-08-21 01:08:56.944","dateFinished":"2020-08-21 01:08:56.952","status":"FINISHED"},{"title":"Paragraph inserted","text":"%md\n\n## Now that you are using Zeppelin \n* Checkout how to [setup other interpreters](https://zeppelin.apache.org/docs/0.9.0/#available-interpreters)\n* To setup Elasticsearch interpreter and OpenSearch-SQL interpreters [checkout](https://github.com/opensearch-project/dashboards-notebooks/blob/dev/docs/dev/Zeppelin_backend_adaptor.md#apache-zeppelin-setup)\n","user":"anonymous","dateUpdated":"2020-08-21 01:08:52.286","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Now that you are using Zeppelin \n
\n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958104590_1715920734","id":"paragraph_1596742076640_674206137","dateCreated":"2020-08-20 21:15:04.590","dateStarted":"2020-08-21 01:08:52.288","dateFinished":"2020-08-21 01:08:52.295","status":"FINISHED"},{"title":"Paragraph inserted","text":"%md\n\n### Hover between paragraphs to add a Saved Visualization or a New Paragraph\n2. **Unpin** the container to *edit the size* or *delete it*\n3. **Refresh** the container after *date is changed*","user":"anonymous","dateUpdated":"2020-08-21 01:09:14.147","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Hover between paragraphs to add a Saved Visualization or a New Paragraph \n
\nUnpin the container to edit the size or delete it \nRefresh the container after date is changed \n \n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958104590_931410594","id":"paragraph_1596524302932_2112910756","dateCreated":"2020-08-20 21:15:04.590","dateStarted":"2020-08-21 01:09:14.149","dateFinished":"2020-08-21 01:09:14.160","status":"FINISHED"},{"title":"CODE","text":"%md\n\n# Start typing here","user":"anonymous","dateUpdated":"2020-08-21 00:56:41.827","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Start typing here \n\n"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597971380477_32105829","id":"paragraph_1597971380477_32105829","dateCreated":"2020-08-21 00:56:20.477","dateStarted":"2020-08-21 00:56:41.830","dateFinished":"2020-08-21 00:56:41.836","status":"FINISHED"}],"name":"Introduction Notebook-Zeppelin","id":"2FJH8PW8K","defaultInterpreterGroup":"spark","version":"0.9.0-preview2","noteParams":{},"noteForms":{},"angularObjects":{},"config":{"isZeppelinNotebookCronEnable":false},"info":{}}
diff --git a/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Log Analysis-Zeppelin.json b/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Log Analysis-Zeppelin.json
new file mode 100644
index 000000000..61571248e
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/example_notebooks/zeppelin/Log Analysis-Zeppelin.json
@@ -0,0 +1 @@
+{"paragraphs":[{"title":"CODE","text":"%md\n## Let's use Zeppelin Adaptor to explore data with Inter-Para Communication\n* Before diving into this notebook make sure:\n * You have integrated [**Sample web logs**](https://www.elastic.co/guide/en/kibana/7.8/getting-started.html#get-data-in)\n * You have used the **Introduction Notebook**\n * You have setup a [**python interpreter**](https://zeppelin.apache.org/docs/0.9.0/interpreter/python.html) & [**OpenSearch-SQL interpreter**](https://github.com/opensearch-project/dashboards-notebooks/blob/dev/docs/dev/Zeppelin_backend_adaptor.md#apache-zeppelin-setup)","user":"anonymous","dateUpdated":"2020-08-21 01:07:36.617","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Let’s use Zeppelin Adaptor to explore data with Inter-Para Communication \n
\nBefore diving into this notebook make sure:\n\n \n \n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597970420851_2109527240","id":"paragraph_1597970420851_2109527240","dateCreated":"2020-08-21 00:40:20.851","dateStarted":"2020-08-21 01:07:36.619","dateFinished":"2020-08-21 01:07:36.626","status":"FINISHED"},{"title":"CODE","text":"%md\n## We'll use the pre-indexed sample web logs provided by OpenSearch Dashboards \n* Make an OpenSearch-SQL query \n* Import the output of SQL query in a python paragraph\n* Plot an anomaly graph using python-matplot","user":"anonymous","dateUpdated":"2020-08-21 00:58:02.620","config":{},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
We’ll use the pre-indexed sample web logs provided by OpenSearch Dashboards \n
\nMake an OpenSearch-SQL query \nImport the output of SQL query in a python paragraph \nPlot an anomaly graph using python-matplot \n \n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597971322703_978148592","id":"paragraph_1597971322703_978148592","dateCreated":"2020-08-21 00:55:22.703","dateStarted":"2020-08-21 00:58:02.629","dateFinished":"2020-08-21 00:58:02.634","status":"FINISHED"},{"title":"Paragraph inserted","text":"%md\n**OpenSearch-SQL Query to fetch size of request and agent data for all the web requests made**\nSelect bytes,agent from opensearch_dashboards_sample_data_logs\n","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.576","config":{"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
OpenSearch-SQL Query to fetch size of request and agent data for all the web requests made \nSelect bytes,agent from opensearch_dashboards_sample_data_logs
\n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173576_437396150","id":"paragraph_1591897831553_-310393619","dateCreated":"2020-08-20 21:16:13.576","status":"READY"},{"title":"Paragraph inserted","text":"%opensearchsql(saveAs=data_logs)\nselect bytes,agent from opensearch_dashboards_sample_data_logs","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.576","config":{"saveAs":"opensearch_dashboards_sample_data_logs","editorSetting":{"language":"sql","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/sql","fontSize":9,"results":{"0":{"graph":{"mode":"table","height":300,"optionOpen":false,"setting":{"table":{"tableGridState":{},"tableColumnTypeState":{"names":{"bytes":"string","agent":"string"},"updated":false},"tableOptionSpecHash":"[{\"name\":\"useFilter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable filter for columns\"},{\"name\":\"showPagination\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable pagination for better navigation\"},{\"name\":\"showAggregationFooter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable a footer for displaying aggregated values\"}]","tableOptionValue":{"useFilter":false,"showPagination":false,"showAggregationFooter":false},"updated":false,"initialized":false}},"commonSetting":{}}}},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"TABLE","data":"bytes\tagent\n6219\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6850\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n14113\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2492\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n1872\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4531\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3629\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n9797\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9920\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6936\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8489\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2860\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8535\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4529\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9888\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n5919\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9890\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n3039\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8766\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8261\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5028\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8130\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9934\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3314\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2492\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n1950\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n0\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8489\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9029\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2860\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8120\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3930\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3464\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8535\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n17403\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9773\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n875\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n18082\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n6514\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8323\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8364\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n6274\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n2108\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7174\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5846\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n7594\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7169\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n9338\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9217\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8390\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9101\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6936\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4634\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8909\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7343\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4939\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n55\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n1778\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8996\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5197\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2153\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n5223\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n178\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5400\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8676\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n6960\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n18409\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2441\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n3010\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9263\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3853\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4238\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2377\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8928\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n6193\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2372\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6942\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n173\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4877\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n15894\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n7468\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5481\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n6920\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9920\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5476\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2432\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n2034\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9021\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7719\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n4037\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n17598\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n6312\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5835\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2647\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n8655\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n17357\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4064\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n3034\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n1634\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3807\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8738\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3629\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n9446\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7182\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2159\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4861\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3317\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8663\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n1793\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n6648\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3307\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n5052\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4531\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n8995\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4579\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n8522\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7304\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n255\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9052\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6795\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n6739\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n7936\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n7309\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6254\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2453\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3378\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n9375\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n1685\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4154\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5919\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4633\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3039\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5375\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n5424\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n14113\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n3841\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n1638\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n5861\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3994\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n1828\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4529\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5321\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n15990\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4806\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4072\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n4617\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9486\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9888\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n7193\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6429\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n8648\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n7377\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9371\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n8590\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2765\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9424\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9716\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n1858\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2432\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n9797\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n2999\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n6817\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4842\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n16227\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n1603\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n19561\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n1936\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5540\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n7085\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5767\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n2053\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n4061\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n7675\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n0\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n979\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n685\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n6509\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n8723\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n9414\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3086\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n1872\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9174\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n5073\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n10103\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7531\tMozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\n5988\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7009\tMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\n6540\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n0\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n9952\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n7873\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n3050\tMozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1\n"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173576_876823109","id":"paragraph_1591897481776_702487776","dateCreated":"2020-08-20 21:16:13.576","status":"READY"},{"title":"Paragraph inserted","text":"%md\n**Import this query output in python**\n","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.577","config":{"tableHide":false,"editorSetting":{"language":"markdown","editOnDblClick":true,"completionSupport":false},"colWidth":12,"editorMode":"ace/mode/markdown","fontSize":9,"editorHide":true,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Import this query output in python
\n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173576_599341048","id":"paragraph_1591897902017_-1544489575","dateCreated":"2020-08-20 21:16:13.577","status":"READY"},{"title":"Paragraph inserted","text":"%python.ipython\n%matplotlib inline\nlogs = z.getAsDataFrame('data_logs')\nlogs","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.577","config":{"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n\n
\n \n \n \n bytes \n agent \n \n \n \n \n 0 \n 6219 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 1 \n 6850 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 2 \n 0 \n Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.... \n \n \n 3 \n 14113 \n Mozilla/4.0 (compatible; MSIE 6.0; Windows NT ... \n \n \n 4 \n 2492 \n Mozilla/4.0 (compatible; MSIE 6.0; Windows NT ... \n \n \n ... \n ... \n ... \n \n \n 195 \n 6540 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 196 \n 0 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 197 \n 9952 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 198 \n 7873 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n 199 \n 3050 \n Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Geck... \n \n \n
\n
200 rows × 2 columns
\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173577_325755404","id":"paragraph_1591898708896_1841265952","dateCreated":"2020-08-20 21:16:13.577","status":"READY"},{"title":"Paragraph inserted","text":"\n%md\n**Plot a scatter graph for requests made per browser using matplot**\n","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.577","config":{"editorSetting":{"language":"scala","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/scala","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"\n
Plot a scatter graph for requests made per browser using matplot
\n\n
"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173577_2096035472","id":"paragraph_1591899582298_-864868294","dateCreated":"2020-08-20 21:16:13.577","status":"READY"},{"title":"Paragraph inserted","text":"%python.ipython\n\n%matplotlib inline\n\nimport warnings\nimport numpy as np\nwarnings.filterwarnings(\"ignore\")\nimport matplotlib.pyplot as plt\n\nlogs = z.getAsDataFrame('data_logs')\nagent_with_firefox = logs['agent'].str.count('Firefox').values\nfirefox_bytes = logs['bytes'].values[agent_with_firefox==1]\n\nagent_with_chrome_safari = logs['agent'].str.count('Chrome').values\nchrome_bytes = logs['bytes'].values[agent_with_chrome_safari==1]\n\nagent_with_msie = logs['agent'].str.count('MSIE').values\nmsie_bytes = logs['bytes'].values[agent_with_msie==1]\n\nprint(\"Total Requests:\", len(agent_with_firefox))\nprint(\"# Requests from Firefox Browser\", np.sum(agent_with_firefox))\nprint(\"# Requests from Chrome/Safari Browser\", np.sum(agent_with_chrome_safari))\nprint(\"# Requests from MSIE Browser\", np.sum(agent_with_msie), \"\\n\\n\")\n\nplt.figure(num=None, figsize=(30, 6))\nplt.title(\"Request size for each browser\")\nplt.ylabel('Request Size in Bytes')\nplt.xlabel('Requests made')\nplt.axhline(y=10000, color='r', linestyle='--')\nplt.plot(msie_bytes, 'ro', markersize=5, label=\"MSIE\")\nplt.plot(firefox_bytes, 'bo', markersize=5, label=\"Firefox\")\nplt.plot(chrome_bytes, 'go', markersize=5, label=\"Chrome\")\nplt.legend()\n\n\n\n\n \n","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.577","config":{"editorSetting":{"language":"python","editOnDblClick":false,"completionKey":"TAB","completionSupport":true},"colWidth":12,"editorMode":"ace/mode/python","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"TEXT","data":"Total Requests: 200\n# Requests from Firefox Browser 86\n# Requests from Chrome/Safari Browser 54\n# Requests from MSIE Browser 60 \n\n\n\n"},{"type":"IMG","data":"iVBORw0KGgoAAAANSUhEUgAABs0AAAGDCAYAAABgLF6CAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdfXxcZZ3w/8+3U0oxEQSsAq3YSkEBhUSKcXVRlIc4GB5cWaEKVFll8WHVvX1kb9Zqyy56q/f6w1VWXAERtuINPmB1NiBaQIVoamJBUShYpaWFCiuQ8FA6vX5/nJMyadMkbWcyk+Tzfr3mdc65ztP3zJxMzpzvua4rUkpIkiRJkiRJkiRJk9mUegcgSZIkSZIkSZIk1ZtJM0mSJEmSJEmSJE16Js0kSZIkSZIkSZI06Zk0kyRJkiRJkiRJ0qRn0kySJEmSJEmSJEmTnkkzSZIkSZIkSZIkTXomzSRJkiRpjEXEURHx+xps94KI+HNErKv2tqslIi6PiAtGuezsiEgRMbXWcUmSJEmSSTNJkiRJDSEiVkXEExHRFxHr8uRKc73j2paIODoiVu/IuimlW1JKL65yPC8APgQcklLap5rbliRJkqTJwKSZJEmSpEZyYkqpGWgBWoHz6hzPePJC4KGU0oPbu+JEqcnVaMcREYV6xyBJkiRp9EyaSZIkSWo4KaV1QCdZ8gyAiNg1Ij4XEX+KiAci4j8iYreK+R+JiLURcX9EnJ036zc3n7csIt5ZsezbI+KnFdMviYgbIuLhiPh9RLylYt4JEfHbiHgsItZExIcjogkoAfvlNeP6ImK/LY9jqHXz8s211CLitIpt9EXEUxGxbDTHXLGfY4EbKuK5PC8/KSJ+ExF/yd+DgyvWWRURH4uIFUD/UAmnEd6XN0ZET0Q8GhH3RcQnt1j3ryPi5/m+74uIt1fM3jMifpC/L10RccCW+97C2fnnujYiPlSxj09GxDURcWVEPAq8PX/PvpAvf38+vmu+/E0R8eaK+FJEnDDwHkZEbz4+N1/2kby5y6tH+Z5cHhEXR8QPI6IfeN0IxyVJkiSpgZg0kyRJktRwImIWUARWVhR/BjiILJE2F5gJfCJf/g3Ah4HjgAOBY7djX01kCaf/Ap4HzAe+HBGH5ot8Dfj7lNKzgZcCP04p9efx3Z9Sas5f9w+x+a3W3XKBlNLVA9sA9gPuBZaMdMxbbONHW8Tz9og4KN/OB4EZwA+B70fEtIpV5wNvBJ6TUtq4ne9LP3AW8Jx8G++OiFPydfcnSyp+Md93C9C7xX4/BexJ9hn/yxDvXaXXkX2uxwMfz5OEA04GrsnjuAr438Ar830eDrwCOD9f9ibg6Hz8NWTv9Wsrpm/KxxcD1+fxzcqPYzTvCcBb8+N5NvBTJEmSJI0bJs0kSZIkNZLvRsRjwH3Ag8BCgIgI4F3AP6aUHk4pPQb8K3B6vt5bgMtSSnfkCa1Pbsc+O4BVKaXLUkobU0q/Aq4FTs3nPw0cEhG7p5T+J58/WqNeNyKmkCVjlqWUvjKKYx7JacAPUko3pJSeBj4H7Aa8qmKZi1JK96WUnhhi/WHfl5TSspTS7SmlTSmlFWQJuoEE1NuAH6WUlqSUnk4pPZRSqkyafTul9Is8UXcVFTUKt+FTKaX+lNLtwGVkyaoBt6aUvpvH8US+70UppQdTSuvJknNn5svexOAk2YUV06/lmaTZ02TNXe6XUnoypTSQ/BrpXAH4XkrpZ3k8T45wXJIkSZIaiEkzSZIkSY3klLxW1tHAS4Dn5uUzgGcBy/Pm/v4C/HdeDlkNrfsqtvPH7djnC4G2ge3m234bsE8+/83ACcAf8yb7/mo7tr096w7UTnp/Pj3SMY9kPyreh5TSJrL3aGbFMvdtuVKFYd+XiGiLiJ9ExPqIeAQ4l2c+rxcA9wyz7XUV448DzSMcy5af7X7bmAdbHPcWy98KHBQRzydL1F0BvCAinktWI+3mfLmPAgH8Im/e8uy8fKRzZah4JEmSJI0TDdVJsiRJkiQBpJRuyvvl+hxwCvBn4Ang0JTSmiFWWUuWqBmw/xbz+8kSUAO2THLclFI6bhux/BI4OSJ2Ad4HfCvfVxrFcWxr3UEi4nSy2lNH5rXCYORjHsn9wMsq9hH5viu3NdwxDPu+kNWK+3egmFJ6MiK+wDNJs/vIklDV8gLgd/n4/mTHNmDLY7ifLLn1my2XTyk9HhHLgQ8Ad6SUNkTEz4H/BdyTUvpzvtw6slp+RMRfAz+KiJsZ+T0ZKh5JkiRJ44Q1zSRJkiQ1qi8Ax0VES15L6qvAv0XE8wAiYmZEtOfLfgt4e0QcEhHPIm/WsUIv8DcR8ayImAv8XcW8pWS1j86MiF3y15ERcXBETIuIt0XEHnky61GgnK/3ALB3ROwxVPAjrFu5XCtZn1mn5M0JAptrhg13zCP5FvDGiDgmT9p9CHgK+Pko19/m+5LPfzbwcJ4wewVZX14DrgKOjYi3RMTUiNg7IkZqgnE4/5x/docC7wCuHmbZJcD5ETEjr0H2CeDKivk3kSUwB5piXLbFNBHxt3m/egD/Q5YIKzPyeyJJkiRpHDNpJkmSJKkh5QmkK4B/zos+BqwEbouIR4EfAS/Oly2RJdl+nC/z4y0292/ABrJE19fJkjoD+3kMOJ6sr7D7yZoO/Aywa77ImcCqfJ/nAmfk6/2OLEFzb95UX2WTgQy37hZOBvYEfhoRffmrNNIxjySl9Pt8f18kq7V2InBiSmnDKNcf6X15D7Ao74PuE2RJuoF1/0TWLOWHgIfJkpaHj2a/23AT2ftwI/C5lNL1wyx7AdANrABuB36Vl1Vu69k80xTjltMARwJdEdEHXAd8IKX0h1G8J5IkSZLGsUjJliMkSZIkTTwRkYADU0or6x2LJEmSJKnxWdNMkiRJkiRJkiRJk55JM0mSJEmSJEmSJE16Ns8oSZIkSZIkSZKkSc+aZpIkSZIkSZIkSZr0TJpJkiRJkiRJkiRp0pta7wDG2nOf+9w0e/bseochSZIkSZIkSZKkMbZ8+fI/p5RmDDVv0iXNZs+eTXd3d73DkCRJkiRJkiRJ0hiLiD9ua57NM0qSJEmSJEmSJGnSM2kmSZIkSZIkSZKkSa9mSbOIeEFE/CQi7oyI30TEB/LyvSLihoi4Ox/umZdHRFwUESsjYkVEvLxiWwvy5e+OiAUV5UdExO35OhdFRNTqeCRJkiRJkiRJkjRx1bJPs43Ah1JKv4qIZwPLI+IG4O3AjSmlT0fEx4GPAx8DisCB+asNuBhoi4i9gIXAPCDl27kupfQ/+TLnALcBPwTeAJRqeEySJEmSJEmSJEl18/TTT7N69WqefPLJeofS0KZPn86sWbPYZZddRr1OzZJmKaW1wNp8/LGIuBOYCZwMHJ0v9nVgGVnS7GTgipRSAm6LiOdExL75sjeklB4GyBNvb4iIZcDuKaVb8/IrgFMwaSZJkiRJkiRJkiao1atX8+xnP5vZs2djA3xDSynx0EMPsXr1aubMmTPq9cakT7OImA20Al3A8/OE2kBi7Xn5YjOB+ypWW52XDVe+eohySZIkSZIkSZKkCenJJ59k7733NmE2jIhg77333u7aeDVPmkVEM3At8MGU0qPDLTpEWdqB8qFiOCciuiOie/369SOFLEmSJEmSJEmS1LBMmI1sR96jmibNImIXsoTZVSmlb+fFD+TNLpIPH8zLVwMvqFh9FnD/COWzhijfSkrpkpTSvJTSvBkzZuzcQUmSJEmSJEmSJE1iEcGZZ565eXrjxo3MmDGDjo4OAB544AE6Ojo4/PDDOeSQQzjhhBMAWLVqFS996UsBWLZsGXvssQctLS2bXz/60Y/G/mAq1KxPs8hSeF8D7kwp/d+KWdcBC4BP58PvVZS/LyK+CbQBj6SU1kZEJ/CvEbFnvtzxwHkppYcj4rGIeCVZs49nAV+s1fFIkiRJkiRJkiSNO+UylErQ0wOtrVAsQqGwU5tsamrijjvu4IknnmC33XbjhhtuYObMZ3rQ+sQnPsFxxx3HBz7wAQBWrFgx5HaOOuooli5dulOxVFMta5q9GjgTeH1E9OavE8iSZcdFxN3Acfk0wA+Be4GVwFeB9wCklB4GFgO/zF+L8jKAdwP/ma9zD1Cq4fFIkiRJkiap8qYyS+9ayuKbFrP0rqWUN5XrHZIkSZI0snIZ2tth/nxYuDAbtrdn5TupWCzygx/8AIAlS5Ywf/78zfPWrl3LrFnPNBZ42GGH7fT+xkLNapqllH7K0P2OARwzxPIJeO82tnUpcOkQ5d3AS3ciTEmSJEmShlXeVKb9yna61nTRv6GfpmlNtM1so/OMTgpTdu4JXUmSJKmmSiXo6oK+vmy6ry+bLpUgb0pxR51++uksWrSIjo4OVqxYwdlnn80tt9wCwHvf+15OO+00/v3f/51jjz2Wd7zjHey3335bbeOWW26hpaVl8/S1117LAQccsFNx7Yya9mkmSZIkSdJ4V1pZomtNF30b+kgk+jb00bWmi9JKGzuRJElSg+vpgf7+wWX9/dDbu9ObPuyww1i1ahVLlizZ3GfZgPb2du69917e9a538bvf/Y7W1lbWr1+/1TaOOuooent7N7/qmTADk2aSJEmSJA2rZ20P/RsG32jo39BP77qdv9EgSZIk1VRrKzQ1DS5raoKK2l0746STTuLDH/7woKYZB+y111689a1v5Rvf+AZHHnkkN998c1X2WUsmzSRJkiRJGkbrvq00TRt8o6FpWhMt+1TnRoMkSZJUM8UitLVBczNEZMO2tqy8Cs4++2w+8YlP8LKXvWxQ+Y9//GMef/xxAB577DHuuece9t9//6rss5Zq1qeZJEmSJEkTQXFukbaZbVv1aVacW50bDZIkSVLNFArQ2Zn1Ydbbm9UwKxaz8iqYNWsWH/jAB7YqX758Oe973/uYOnUqmzZt4p3vfCdHHnkkq1atGrTcln2anX/++Zx66qlViW1HREqpbjuvh3nz5qXu7u56hyFJkiRJGkfKm8qUVpboXddLyz4tFOcWKUypzo0GSZIkaXvceeedHHzwwfUOY1wY6r2KiOUppXlDLW9NM0mSJEmSRlCYUqDjoA46DuqodyiSJEmSasQ+zSRJkiRJkiRJkjTpmTSTJEmSJEmSJEnSpGfSTJIkSZIkSZIkSZOeSTNJkiRJkiRJkiRNeibNJEmSJEmSJEmSNOmZNJMkSZIkSZIkSdKoFQoFWlpaNr9WrVpFd3c373//+7d7Wx/5yEc49NBD+chHPlKDSLfP1HoHIEmSJEmSJEmSpNool6FUgp4eaG2FYhEKhZ3b5m677UZvb++gstmzZzNv3rytlt24cSNTp247HfWVr3yF9evXs+uuu+5cUFVgTTNJkiRJkiRJkqQJqFyG9naYPx8WLsyG7e1ZebUtW7aMjo4OAD75yU9yzjnncPzxx3PWWWdRLpf5yEc+wpFHHslhhx3GV77yFQBOOukk+vv7aWtr4+qrr+aPf/wjxxxzDIcddhjHHHMMf/rTnwA4+eSTueKKK4Asyfa2t72t+geANc0kSZIkSZIkSZImpFIJurqgry+b7uvLpkslyPNbO+SJJ56gpaUFgDlz5vCd73xnq2WWL1/OT3/6U3bbbTcuueQS9thjD375y1/y1FNP8epXv5rjjz+e6667jubm5s211k488UTOOussFixYwKWXXsr73/9+vvvd73LJJZfw6le/mjlz5vD5z3+e2267bceDH4ZJM0mSJEmSJEmSpAmopwf6+weX9fdDb+/OJc2Gap5xSyeddBK77bYbANdffz0rVqzgmmuuAeCRRx7h7rvvZs6cOYPWufXWW/n2t78NwJlnnslHP/pRAJ7//OezaNEiXve61/Gd73yHvfbaa8eDH4ZJM0nSxFKLRpolSZIkSZKkcai1FZqanqlpBtl0XkmsppqamjaPp5T44he/SHt7+3ZtIyI2j99+++3svffe3H///VWLcUv2aSZJmjjGspFmSZIkSZIkqcEVi9DWBs3NEJEN29qy8rHU3t7OxRdfzNNPPw3AXXfdRf+WVeCAV73qVXzzm98E4KqrruKv//qvAfjFL35BqVSip6eHz33uc/zhD3+oSZzWNJMkTRy1aqRZkiRJkiRJGocKBejszG6P9fZmNczq0TDTO9/5TlatWsXLX/5yUkrMmDGD7373u1std9FFF3H22Wfz2c9+lhkzZnDZZZfx1FNP8a53vYvLLruM/fbbj89//vOcffbZ/PjHPx5UE60aIqVU1Q02unnz5qXu7u56hyFJqoXFi7MaZpX/2yJg0SI4//z6xSVJkiRJkiRVyZ133snBBx9c7zDGhaHeq4hYnlKaN9TyNs8oSZo4BhpprjRWjTRLkiRJkiRJGtdMmknSKJQ3lVl611IW37SYpXctpbzJPrIaUqM00ixJkiRJkiRp3LFPM0kaQXlTmfYr2+la00X/hn6apjXRNrONzjM6KUwZ48Z/NbxGaaRZkiRJkiRJ0rhj0kySRlBaWaJrTRd9G/oA6NvQR9eaLkorS3Qc1FHn6LSVQgE6OrKXJEmSJEmSJI2SzTNK0gh61vbQv6F/UFn/hn561/XWKSJJkiRJkiRJUrWZNJOkEbTu20rTtKZBZU3TmmjZp6VOEUmSJEmSJEmSqs2kmSSNoDi3SNvMNpqnNRMEzdOaaZvZRnFusd6hSZIkSZIkSdKYW7duHaeffjoHHHAAhxxyCCeccAKXXHIJHeO8yxT7NJOkERSmFOg8o5PSyhK963pp2aeF4twihSmFeocmSZIkSZIkScMqbypTWlmiZ20Prfu27vS9zZQSb3rTm1iwYAHf/OY3Aejt7eX73//+6OIplykUGvPeqkkzSRqFwpQCHQd10HHQ+H5SQlLtVftCVJIkSZIkaUeVN5Vpv7KdrjVd9G/op2laE20z2+g8o3OH71f85Cc/YZddduHcc8/dXNbS0sJf/vIXbrzxRk499VTuuOMOjjjiCK688koigtmzZ3P22Wdz/fXX8773vY+XvOQlnHvuuTz++OMccMABXHrppey5554cffTRtLa2snz5ctavX88VV1zBhRdeyO23385pp53GBRdcAMCVV17JRRddxIYNG2hra+PLX/5yVRJxNWueMSIujYgHI+KOirKrI6I3f62KiN68fHZEPFEx7z8q1jkiIm6PiJURcVFERF6+V0TcEBF358M9a3UskiRJozFwITr/2vksXLaQ+dfOp/3KdsqbyvUOTZIkSZIkTUKllSW61nTRt6GPRKJvQx9da7oorSzt8DYHEmJD6enp4Qtf+AK//e1vuffee/nZz362ed706dP56U9/yumnn85ZZ53FZz7zGVasWMHLXvYyPvWpT21ebtq0adx8882ce+65nHzyyXzpS1/ijjvu4PLLL+ehhx7izjvv5Oqrr+ZnP/sZvb29FAoFrrrqqh0+nkq17NPscuANlQUppdNSSi0ppRbgWuDbFbPvGZiXUjq3ovxi4BzgwPw1sM2PAzemlA4EbsynJUmS6qYWF6KSJEmSJEk7qmdtD/0b+geV9W/op3ddb03294pXvIJZs2YxZcoUWlpaWLVq1eZ5p512GgCPPPIIf/nLX3jta18LwIIFC7j55ps3L3fSSScB8LKXvYxDDz2Ufffdl1133ZUXvehF3Hfffdx4440sX76cI488kpaWFm688UbuvffeqsRfs+YZU0o3R8TsoebltcXeArx+uG1ExL7A7imlW/PpK4BTgBJwMnB0vujXgWXAx3Y+cknSeFYuQ6kEPT3Q2grFIjRoE8magIa7ELV5V0mSJEmSNNZa922laVoTfRv6Npc1TWuiZZ+WHd7moYceyjXXXDPkvF133XXzeKFQYOPGjc/st6lpVNsf2MaUKVMGbW/KlCls3LiRlBILFizgwgsv3JHwh1XLmmbDOQp4IKV0d0XZnIjoiYibIuKovGwmsLpimdV5GcDzU0prAfLh82odtCSpsZXL0N4O8+fDwoXZsL09K5fGwsCFaKUdvRAtbyqz9K6lLL5pMUvvWmoTj5IkSZIkabsV5xZpm9lG87RmgqB5WjNtM9sozi3u8DZf//rX89RTT/HVr351c9kvf/lLbrrpplGtv8cee7Dnnntyyy23APCNb3xjc62z0TjmmGO45pprePDBBwF4+OGH+eMf/7gdR7BtNatpNoL5wJKK6bXA/imlhyLiCOC7EXEoEEOsm7Z3ZxFxDlkTj+y///47EK4kaTwolaCrC/ryB2f6+rLpUgk6rOSjMTBwIbpl57rbeyFai056JUmSJEnS5FOYUqDzjE5KK0v0ruulZZ8WinOLO3V/ISL4zne+wwc/+EE+/elPM336dGbPns0pp5wy6m18/etf59xzz+Xxxx/nRS96EZdddtmo1z3kkEO44IILOP7449m0aRO77LILX/rSl3jhC1+4I4czSKS03Tmo0W88a55xaUrppRVlU4E1wBEppdXbWG8Z8OF8uZ+klF6Sl88Hjk4p/X1E/D4fX5s347gspfTikWKaN29e6u7u3rkDkyQ1pMWLsxpmlf/aImDRIjj//PrFpcmlvKm80xeiS+9ayvxr5w9qOqF5WjNL3rzEZh4lSZIkSZrk7rzzTg4++OB6hzEuDPVeRcTylNK8oZavR/OMxwK/q0yYRcSMiCjk4y8CDgTuzZtdfCwiXpn3g3YW8L18teuABfn4gopySdIk1doKWzaN3NQELTveRLO03QpTCnQc1MH5rzmfjoM6dujJrbHupFeSJEmSJEk1TJpFxBLgVuDFEbE6Iv4un3U6g5tmBHgNsCIifg1cA5ybUno4n/du4D+BlcA9QCkv/zRwXETcDRyXT0uSJrFiEdraoLk5q2HW3JxNF3e8iWapLqrZN5okSZIkSZJGp2Z9mqWU5m+j/O1DlF0LXLuN5buBlw5R/hBwzM5FKUmaSAoF6OzM+jDr7c1qmBWLWbk0nlSrbzRJkiRJkiSNXs2SZpIk1UOhAB0d2Usar2rRSa8kSZIkSZo4UkpkvVppW1JK272OSTNJkqQGNNA3WsdBZoAlSZIkSdIzpk+fzkMPPcTee+9t4mwbUko89NBDTJ8+fbvWM2kmSZIkSZIkSZI0TsyaNYvVq1ezfv36eofS0KZPn86sWbO2ax2TZpIkSZIkSZIkSePELrvswpw5c+odxoQ0pd4BSJIkSZIkSZIkSfVm0kySJEmSJEmSJEmTnkkzSZIkSZIkSZIkTXomzSRJkiRJkiRJkjTpmTSTJEmSJEmSJEnSpGfSTJIkSZIkSZIkSZOeSTNJkiRJkiRJkiRNelPrHYAkSZIkSVJVlctQKkFPD7S2QrEIhUK9o5IkSVKDM2kmSZIkSZImjnIZ2tuhqwv6+6GpCdraoLPTxJkkSZKGZfOMkiRJkiRp4iiVsoRZXx+klA27urJySZIkaRgmzSRJkiRJ0sTR05PVMKvU3w+9vfWJR5IkSeOGzTNKkiRJkqSJo7U1a5Kxr++ZsqYmaGmpX0yqObuxkyRJ1WDSTJIk1U15U5nSyhI9a3to3beV4twihSne3ZAkSTuhWMz6MNuyT7Nisd6RqUbsxk6SJFWLSTNJklQX5U1l2q9sp2tNF/0b+mma1kTbzDY6z+g0cSZJknZcoZBlS0qlrEnGlharHU1wld3YweBu7Do66hubJEkaX+zTTJIk1UVpZYmuNV30begjkejb0EfXmi5KK0v1Dk2SJI13hUKWLTn//GxowmxCsxs7SZJULSbNJElSXfSs7aF/w+C7G/0b+uld590NSZIkjd5AN3aV7MZOkiTtCJNmkiSpLlr3baVp2uC7G03TmmjZx7sbkiRJGr2BbuyamyEiG9qNnSRJ2hH2aSZJkuqiOLdI28y2rfo0K8717oYkSZJGz27sJElStURKqd4xjKl58+al7u7ueochSZKA8qYypZUletf10rJPC8W5RQpTvLshSZIkSZKk2oiI5SmleUPNs6aZJEmqm8KUAh0HddBxUEe9Q5EkSZIkSdIkZ59mkiRJkiRJkiRJmvRMmkmSJEmSJEmSJGnSM2kmSZIkSZIkSZKkSc+kmSRJkiRJkiRJkiY9k2aSJEmSJEmSJEma9GqWNIuISyPiwYi4o6LskxGxJiJ689cJFfPOi4iVEfH7iGivKH9DXrYyIj5eUT4nIroi4u6IuDoiptXqWCRJkiRJkiRJkjSx1bKm2eXAG4Yo/7eUUkv++iFARBwCnA4cmq/z5YgoREQB+BJQBA4B5ufLAnwm39aBwP8Af1fDY5EkSZIkSZIkSdIEVrOkWUrpZuDhUS5+MvDNlNJTKaU/ACuBV+SvlSmle1NKG4BvAidHRACvB67J1/86cEpVD0CSJEmSJEmSJEmTRj36NHtfRKzIm2/cMy+bCdxXsczqvGxb5XsDf0kpbdyiXJIkSZIkSZIkSdpuY500uxg4AGgB1gKfz8tjiGXTDpQPKSLOiYjuiOhev3799kUsSZIkSZIkSZKkCW9Mk2YppQdSSuWU0ibgq2TNL0JWU+wFFYvOAu4fpvzPwHMiYuoW5dva7yUppXkppXkzZsyozsFIkiRJkiRJkiRpwhjTpFlE7Fsx+Sbgjnz8OuD0iNg1IuYABwK/AH4JHBgRcyJiGnA6cF1KKQE/AU7N118AfG8sjkGSJEmSJEmSJEkTz9SRF9kxEbEEOBp4bkSsBhYCR0dEC1lTiquAvwdIKf0mIr4F/BbYCLw3pVTOt/M+oBMoAJemlH6T7+JjwDcj4gKgB/harY5FkiRJkiRJkiRJE1tklbYmj3nz5qXu7u56hyFJkiRJkiRJkqQxFhHLU0rzhpo3ps0zSpIkSZIkSZIkSY3IpJkkSZIkSZIkSZImPZNmkiRJkiRJkiRJmvRMmkmSJEmSJEmSJGnSM2kmSZIkSZIkSZKkSW9qvQNQgyqXoVSCnh5obYViEQqFekclSZIkaTzw94QkSZKkccikmbZWLkN7O3R1QX8/NDVBWxt0dvpDV5IkSdLw/D0hSZIkaZyyeUZtrVTKfuD29UFK2bCrKyuXJEmSpOH4e0KSJEnSOGXSTFvr6cmeCK3U3w+9vfWJR5IkSdL44e8JSZIkSeOUSTNtrbU1a0KlUlMTtLTUJx5JkiRJ44e/JyRJkiSNU6OC6cYAACAASURBVCbNtLViMetzoLkZIrJhW1tWLkmSJEnD8feEJEmSpHFqar0DUAMqFLJOukulrAmVlpbsB66ddkuSJEkaib8nJEmSJI1TkVKqdwxjat68eam7u7veYUiSJEmSJEmSJGmMRcTylNK8oebZPKMkSZIkSZIkSZImPZNmkiRJkiRJkiRJmvRMmkmSJEmSJEmSJGnSM2kmSZIkSZIkSZKkSc+kmSRJkiRJkiRJkiY9k2aSJEmSJEmSJEma9EyaSZIkSZIkSZIkadIzaSZJkiRJkiRJkqRJb8SkWUQcEBG75uNHR8T7I+I5tQ9NkiRJkiRJkiRJGhujqWl2LVCOiLnA14A5wH/VNCpJkiRJkiRJkiRpDI0mabYppbQReBPwhZTSPwL71jYsSZIkSZIkSZIkaeyMJmn2dETMBxYAS/OyXWoXkiRJkiRJkiRJkjS2RpM0ewfwV8C/pJT+EBFzgCtrG5YkSZIkSZIkSZI0dqaOtEBK6bcR8TFg/3z6D8Cnax2YJEmSJEmSJEmSNFZGrGkWEScCvcB/59MtEXFdrQOTJEmSJEmSJEmSxspommf8JPAK4C8AKaVeYE4NY5IkSZIkSZIkSZLG1GiSZhtTSo9sUZZGWikiLo2IByPijoqyz0bE7yJiRUR8JyKek5fPjognIqI3f/1HxTpHRMTtEbEyIi6KiMjL94qIGyLi7ny45+gOWZIkSZIkSZIkSRpsNEmzOyLirUAhIg6MiC8CPx/FepcDb9ii7AbgpSmlw4C7gPMq5t2TUmrJX+dWlF8MnAMcmL8Gtvlx4MaU0oHAjfm0JEmSJEmSJEmStN1GkzT7B+BQ4Cngv4BHgA+MtFJK6Wbg4S3Krk8pbcwnbwNmDbeNiNgX2D2ldGtKKQFXAKfks08Gvp6Pf72iXJIkSZIkSZIkSdouo0mavTGl9L9TSkfmr/OBk6qw77OBUsX0nIjoiYibIuKovGwmsLpimdV5GcDzU0prAfLh87a1o4g4JyK6I6J7/fr1VQhdkiRJkiRJkiRJE8lokmbnjbJs1CLifwMbgavyorXA/imlVuB/Af8VEbsDMcTqI/anttUKKV2SUpqXUpo3Y8aMHQ1bkiRJkiRJkiRJE9TUbc2IiCJwAjAzIi6qmLU7WcJrh0TEAqADOCZvcpGU0lNkzT+SUloeEfcAB5HVLKtswnEWcH8+/kBE7JtSWps34/jgjsYkSZIkSZIkSZKkyW24mmb3A93Ak8Dyitd1QPuO7Cwi3gB8DDgppfR4RfmMiCjk4y8CDgTuzZtdfCwiXhkRAZwFfC9f7TpgQT6+oKJckiRJkiRJkiRJ2i7brGmWUvo18OuIeBj4QUpp0/ZsOCKWAEcDz42I1cBCsmYddwVuyHJg3JZSOhd4DbAoIjYCZeDclNLD+abeDVwO7EbWB9pAP2ifBr4VEX8H/An42+2JT5IkSZIkSZIkSRoQeQuJ214g4krgr4BrgctSSneORWC1Mm/evNTd3V3vMCRJkiRJkiRJkjTGImJ5SmneUPOGa54RgJTSGUArcA9wWUTcGhHnRMSzqxynJEmSJEmSJEmSVBcjJs0AUkqPktU0+yawL/Am4FcR8Q81jE2SJEmSJEmSJEkaEyMmzSLixIj4DvBjYBfgFSmlInA48OEaxydJkiRJkiRJkiTV3NRRLPO3wL+llG6uLEwpPR4RZ9cmLEmSJEmSJEmSJGnsjJg0SymdNTAeEc8FHkoppXzejTWMTZIkSZIkSZIkSRoT22yeMSJeGRHLIuLbEdEaEXcAdwAPRMQbxi5ESZIkSZIkSZIkqbaGq2n278A/AXuQ9WdWTCndFhEvAZYA/z0G8UmSJEmSJEmSJEk1t82aZsDUlNL1KaX/B6xLKd0GkFL63diEJkmSJEmSJEmSJI2N4ZJmmyrGn9hiXqpBLJIkSZIkSZIkSVJdDNc84+ER8SgQwG75OPn09JpHJkmSJEmSJEmSJI2RbSbNUkqFsQxEkiRJkiRJkiRJqpfhmmeUJEmSJEmSJEmSJgWTZpIkSZIkSZIkSZr0TJpJkiRJkiRJkiRp0jNpJkmSJEmSJEmSpElvxKRZRPxNRNwdEY9ExKMR8VhEPDoWwUmSJEmSJEmSJEljYeoolvk/wIkppTtrHYwkSZIkSZIkSZJUD6NpnvEBE2aSJEmSJEmSJEmayEZT06w7Iq4Gvgs8NVCYUvp2zaKSJEmSJEmSJEmSxtBokma7A48Dx1eUJcCkmSRJkiRJkiRJkiaEEZNmKaV3jEUgkiRJkiRJkiRJUr1sM2kWER9NKf2fiPgiWc2yQVJK769pZJIkSZIkSZIkSdIYGa6m2Z35sHssApEkSZIkSZIkSZLqZZtJs5TS9/Ph18cuHEmSJEmSJEmSJGnsTal3AJIkSZIkSZIkSVK9mTSTJEmSJEmSJEnSpGfSTJIkSZIkSZIkSZPeiEmziDgoIm6MiDvy6cMi4vzahyZJkiRJkiRJkiSNjdHUNPsqcB7wNEBKaQVwei2DkiRJkiRJkiRJY6tchqVLYfHibFgu1zsiaWyNJmn2rJTSL7Yo2ziajUfEpRHx4EAttbxsr4i4ISLuzod75uURERdFxMqIWBERL69YZ0G+/N0RsaCi/IiIuD1f56KIiNHEJUmSJEmSJEmSnlEuQ3s7zJ8PCxdmw/Z2E2eaXEaTNPtzRBwAJICIOBVYO8rtXw68YYuyjwM3ppQOBG7MpwGKwIH56xzg4nx/ewELgTbgFcDCgURbvsw5FettuS9Jaig+rSNJkiRJkqRGVCpBVxf09UFK2bCrKytXxnt7E9/UUSzzXuAS4CURsQb4A3DGaDaeUro5ImZvUXwycHQ+/nVgGfCxvPyKlFICbouI50TEvvmyN6SUHgaIiBuAN0TEMmD3lNKtefkVwCnA8H/Cv/89HH304LK3vAXe8x54/HE44YSt13n727PXn/8Mp5669fx3vxtOOw3uuw/OPHPr+R/6EJx4Yrbvv//7reeffz4ceyz09sIHP7j1/H/9V3jVq+DnP4d/+qet53/hC9DSAj/6EVxwwdbzv/IVePGL4fvfh89/fuv53/gGvOAFcPXVcPHFW8+/5hp47nPh8suz15Z++EN41rPgy1+Gb31r6/nLlmXDz30u+yaptNtuz3zrLl4MN944eP7ee8O112bj550Ht946eP6sWXDlldn4Bz+YvYeVDjoILrkkGz/nHMp3/Z7S3g/T09xHa18zxRe8jsIXLsrmn3EGrF49eP2/+iu48MJs/M1vhoceAqBMyrZz+PNoPf0fKc4tUnhjBzzxxOD1Ozrgwx/Oxrc876Aq51751NMoXbGenkXX0dq8kuJeXRRiUzbfcy8bNsC5x113UU5TaF/xWboePZj+TdNpap5CWxt0Pu9MCvffN3j9bZx7mx1zDPzzP2fjxWJdzj2/98bPuTdIS0v2/sF2fe9t5rnnuQeee+Pg3CunKZQebqOnb252ffD991CY7bnnuTf+vvfKS79P6f6b6PneV2i9bRXFh/aiQEUDI5572bjn3tbz/Z+bjXvubT3fcy8b99zber7nnuceTPpzr+cf/kh/3zuorGvT35/o7Q06kude+fcrB9/b22UDba+ZTmcnFBZ47m2l0b/3tmHEpFlK6V7g2IhoAqaklB4b9daH9vyU0tp822sj4nl5+Uyg8q7x6rxsuPLVQ5RvJSLOIauRxmG77rqT4Wu8KrOJ9sNX0LX7o/QXNtFUnkJbeoTOTf9GYUphO7aTntlOuoOma39B28w2OpnK6LdCdjPr9hfSsxhaD5lCMU15Jtk12m1sCtrboevWvel//B00TXmStt3vpPOwj2z3tlR7pYfb6Hr0YPo2PQuoeFrniMPpGPQ1J0nSjtvqIY0pT9J2xhQ6b2K7rlWkeiuTaP9/J9G1rpv+DX00HTKFtkd3p/PXhw1OnEmStBM2P2x07SG0NkHxpV4zafJqbV5J05QnN9+7AmjaLdHSEnk7dJPbVvf2np6+uSZeR51jU/VEVrFrmAUiysBngfPyWmBExK9SSi8fdsVn1p8NLE0pvTSf/ktK6TkV8/8npbRnRPwAuDCl9NO8/Ebgo8DrgV1TShfk5f8MPA7cnC9/bF5+FPDRlNKJw8Uzb9681N3dPZrQNcEsvWsp86+dT9+Gvs1lzdOaWfLmJXQcNPqvtWpsZ6B94K4u6O+HpiayGkedUNiOK7OlS7O2hfueCYXmZliyJHsQQVDeVKa0skTP2h5a923NagVuR5K0mhYvztqDrvzajYBFi7IHMyRJqgavDzRRVOv6XZKkbanW/RlpovBvYnje25s4ImJ5SmneUPNG06fZb/Llrs/7FwN26rG+B/JmF8mHD+blq4EXVCw3C7h/hPJZQ5RLQ+pZ20P/hv5BZf0b+uld17uNNWq3nWq1D9zTk/0DGxRL/9Y1iSer8qYy7Ve2M//a+SxctpD5186n/cp2ypvq09hwa2t2sVGpqSmrhSxJUrV4faCJolrX7xOWHWpI0k6z/yZpsEIhS5AtWZIlgpYsMWFWyXt7k8NokmYbU0ofBb4K3BIRR7BzlTGvAxbk4wuA71WUnxWZVwKP5M04dgLHR8SeEbEncDzQmc97LCJeGREBnFWxLWkrrfu20jRt8Lda07QmWvbZvm+1amynWjez/KIeXmllia41XfRt6COR6NvQR9eaLkor63P1WyxmT+c0N2dPoTQ3Z9PFYl3CkSRNUF4faKKo1vX7hDTwGPj8+dnjzvPnZ9MmziRpu/iwkbS1QiFroeL887OhCbNneG9vchhN0iwAUkrfAt4CXAa8aDQbj4glwK3AiyNidUT8HfBp4LiIuBs4Lp8G+CFwL7CSLEH3nny/DwOLgV/mr0V5GcC7gf/M17kH8DkQbVNxbpG2mW00T2smCJqnNdM2s43i3O37VqvGdqp1M8sv6uE12tPJPq0jSRoLXh9ooqjW9fuEZNUISaoKHzaStD28tzc5jKZPsyNSSssrpncHTkkpXVHr4GrBPs0mt4H+rXrX9dKyT8sO92+1s9upZvvA5XL227i3N7uoKxb9oh5gPxiSpMnK6wNNFNW6fp9w7FBDqpmB/6E9PVlCxf+hE5v9N0nS5DRcn2bbTJpFxOtTSj+OiL8Zan5K6dtVjHHMmDRTo/BmVu0N9GnWtaaL/g39NE1rom1mG51ndHqzRZKkccabmJowqnEyL12aNcnY98zDYTQ3Z487d/hwmLSjTKBMTt6fmZy8tpQmtx1Nmn0qpbQwIi4bYnZKKZ1dzSDHikkzaXLx6WSpNvyBIWkseRNTDaEa//yqdTKXy5SPL1L6+R70PHkwrdPvpPiqRyhcX/KPQtoJ5qOlycFrS0nDJc2mbmullNLCfPiOWgUmSbVWmFKg46AOm2OUqsgfGJLGWmX3TTC4+yZvYmpMVOufX5VO5jIF2umkizL9TKGJTbRRoJPAf8XSjuvpyf7EK/X3ZzWQ/H8jTRxeW0oazpRtzYiIEyPihRXTn4iIX0fEdRExZ2zCkyQNqVzOHoNcvDgblsv1jkjbMgE/q8ofGCkN/oEhSbUw3E1MaUxU659flU7mUgm6fhH0PTmVxBT6npxK1y/C/8XSTmptzXLilZqasib7JE0cXltKGs42a5oB/wK8EiAiOoAzgPlAK/AfQHvNo5Mkbc1qPuPHBP2sfAJX0lgbuIlZ2VyWNzE1pqr1z69KJ7P/i6XaKBazy/UtL9+LxXpHJqmaGvHa0i4QpMaxzZpmZP2WPZ6P/w3wtZTS8pTSfwIzah+aJGlIVvMZPyboZ1XNJ3AnYEU8STUwcBOzuRkisqE3MTWmqvXPr0ons7VhpNooFLLn25YsgUWLsuE4f95N0hAa7dpy4Hnb+fNh4cJs2N7u72OpXoaraRYR0Qw8DhwDfLli3vSaRiVp7PlIy/jho8XjxwT9rKr1BO4ErYgnTRiNdGkwcBOzVMq+QltavFSZLBrmPKzWP78qnczWhpFqp1DILtXH8eW6pBE02rWlfaxJjWW4pNkXgF7gUeDOlFI3QES0AmvHIDZJY8U71+NLI7YjoKFN0M+qWj8wJuoPg4a5watxqbypTGlliZ61PbTu20pxbpHClLE/gRrx0sCbmJNPQ52H1by7VoWTudFu9kmSNN400rXlBH3eVhq3tpk0SyldGhGdwPOAX1fMWge8o9aBSRpDE/XO9UTlo8XjxwT+rAqU6aBER+oh6+60CGzfnbpq/jBolERVQ93g1bhT3lSm/cp2utZ00b+hn6ZpTbTNbKPzjM4xT5x5aaBG0HDnYSPdXaPhwpEkSTtogj5vK41bw9U0I6W0BlizRZm1zKSJxkdaxhcfLR4/JupnVaXMULV+GDRSoqrhbvBqXCmtLNG1pou+DdkJ1Lehj641XZRWlug4aGxPIC8N1Ag8DyVJ0mQwgZ+3lcalYZNmkmqnUZpfAnykZTzy0eLxYyJ+VlXKDFXrh0EjJaq8waud0bO2h/4Ng0+g/g399K7rHfOkmZcGagSeh5IkaTKYqM/bSuOVSTOpDhqp+SXAR1rUGBqlfT2NrEqZoWr9MGikRJU3eLUzWvdtpWla0+aaZgBN05po2WcHTqCd/E710kCNwPNwfGmohwIlSRpnJuLzttJ4NWLSLCK+kVI6c6QySaPXSM0vAT7SovprpPb1NLIqZoaq8cOgkRJV3uAdO1W7OdtACfvi3CJtM9u2eqimOHc7T6AqfKd6aaBGUK3z0GRO7TXcQ4GSJEnSDoqU0vALRPwqpfTyiukCcHtK6ZBaB1cL8+bNS93d3fUOQ5Pc4psWs3DZQhLP/P0FwaLXLeL815xfx8ikOlm6FObPH5z1aG6GJUt8zKoRNViSs8HC2ZyDMdFQO1W7OdtoJw/P3NzvXddLyz4tO3Zz3+9UaTOTOWNj6V1LmX/t/EE1ZZunNbPkzUvq81CgpJppoOeNJEnaYRGxPKU0b6h526xpFhHnAf8E7BYRjw4UAxuAS6oepTSJVLX5pSqp1oWvF9DjS8N8Xj09lPueoMQb6aGVVnoo9v03BTuCakwNVgWlwcKxWY0xULUa243UIV6uMKVAx0EdO3eTuZHaLNW40zDXBlXScC08TFCN1CejpNppwOeNJEmqum0mzVJKFwIXRsSFKaXzxjAmacKrWvNLVVKtC18voMeXRvq8yoe10l64ga7yPPp5Fk08Tluhm86X9eOp06AaLDPUYOGoxqp2c3aiJpcaqc1SjSuNdG1QLSZzxkYjPhQoqfoa8HkjSZKqbsoollkaEU0AEXFGRPzfiHhhjeOSJrTClAKdZ3Sy5M1LWPS6RSx585K6NhFTeeGb0uAL33psZyIrbyqz9K6lLL5pMUvvWkp5U7lusWSfVxr8ed2W6vJ5lSjSRRt9PJtEgT6eTRdtlLAjKElbG7g5W2mHbs4OJJcGbWgCJJcGOtdrboaIbGjnehqFiXgtV7XvCw1r4KHA5mnNBEHztOa6PhQoqTaGe95IkqSJYps1zSpcDBweEYcDHwW+BlwBvLaWgUkTXVWaX6qSaj1oP1Ef2Aeq0lZRo/Wp0bN8E/19kLW8m+nvT/T+KtHRMZpnKqoYy4oC/Zt2G1TWv2k3em8POk4e01AkjQNVq7E9kFzaslrNeE8uNVqbpRo3JuK1XKO18DBRDTwUuNN9MkpqaFZmlyRNBqNJmm1MKaWIOBn4/1JKX4uIBbUOTGpoE6yzh2pd+E7YC+gqtVXUaH1qtJa7aeIQ+mjeXNbE47Rs/C3wirGNpRWammKLcyfG/7kjqSaqdnN2IieXbLNUO2AiXsuZzBk7jfRQoKTamKjPG0mSVGk0SbPHIuI84EzgqIgoALvUNiypgU3Azh6qdeE7YS+gq9Rwe6P1qVEsXE8bj9JF2zP9iNFFcWoXY500m7DnjqSaqdrNWZNL0mYT9f+xyRxJqo6J/LyRJEkDRpM0Ow14K3B2SmldROwPfLa2YUkNbAL2fFutC9+qXkA3Um2+nh7KfU9Q4o300EorPRT7/pvCdrZV1GgdpBeOaKGz6c2U+o+ilxZa6KXYdAuFl1819rH440uSpLrz/7EkaSQ+b/T/t3f/UZKddZ3HP9+u0CapCgQ0OMMkgeBkFPxBN5ZpBI0gkqawNbIBTWsQAQ26sOCuugs4x8FpWXFFfuxZDmsIeJBgByQgY0vZCQohLlCkJ9UCIRIbiDCTGYiCkKqYdFL93T/uraSqp7u6q/tW3VvPfb/OmVNTt6qrnvp173Of7/P9PgCA0Jm7b30ns8dKutDdP2JmZ0oquPvdA2/dAJTLZV9aWkq7GRhlc3PSoUPR6uhtZtLhw9LBg+m1KyQZy+ZrfWhB05cVVWuVH8rIKixp8bqmCpdu/0wha2uaZe19BgAAAAAAAIBBM7Oj7l7e6LYtM83M7NckXSnpUZK+R9I+Sf9X0jOTbCQwMkJc7CFrMpbNV1VFNd2nhs6MmqOzVNOUqvoO9dOazK2pwXRyAAAAAAAAAHjQdsozvkzR4jY1SXL3fzazRw+0VUCWhbrYQ5bU69F726nZjAI7KQTN6p8pqLl2Rndz1s7Q8mdNM5f291iZW1OD2hoAgBHRWmupulJV/URdk3sn0514AgAAAAAI0naCZve5+6qZSZLM7DRJW9d0BEJFds7gZSybL2qOrWuOkVwIAMCQZK7EMQAAAADsQqsVDS/X69HYI8PL2bGdoNmNZvYaSWeY2bMk/WdJfz3YZgEZR3bOYGUsmy9jzQEAIHeqK1XVjtfUWI1msDRWG6odr6m6Us1O9jYAAAAAbEOrJU1PnzrWuLhI4CwLthM0e5Wkl0j6rKSXSvqwpKsH2SgAOZexbL6MNQcA+sP0NQSgfqKu5mp36ebmalPLJ5cJmgEAAAAYKdVqFDBrV7VqNKLr1So5GlmwZdDM3dckvT3+BwDDkbFsvow1BwC2h+lrCMTk3kkVx4sPZppJUnG8qIk91EpGfrHOHwAAwGiq16NT9E7NZjRZn7HH9G0ZNDOzL2uDNczc/fEDaREAABgYko5yhulrCERlf0VT+6ZOWdOssp9aycgn1vkDAAAYXZOT0ZzWxkNzAlUsRtWtkL7tlGcsd/z/dEnPl/SonT6hmX2vpPd2bHq8pN+TdLakX5N0V7z9Ne7+4fhvXq2oRGRL0ivcfTHe/mxJb5FUkHS1u79+p+0CACB0JB3lENPXEIjCWEGLVyyqulLV8sllTeyZIKsGucY6f1sjEw8AAGRVpRKNx6wfn6kwJzATtlOe8d/WbXqzmf2DokBX39z9C5ImJMnMCpKOS/qgpBdJepO7v6Hz/mb2REmXS/p+SY+R9BEzOxDf/FZJz5J0TNLNZnbE3T+/k3YBABA6ko62IbRUPKavISCFsYJmDswQEADEOn9bIRMPAABkWaEQTWCuVqM5rRMToz/8EJLtlGd8csfVMUWZZ2cl9PzPlPRFd/8XM9vsPpdKutbd75P0ZTNbkXRRfNuKu38pbue18X0JmgEAsAGSjrYQYioe09cAILwJEWKdv62QiQcAALKuUIjGYhiPyZ7tlGf8k47/PyDpDkk/n9DzXy5pvuP6y83slyUtSfotd/+mpH2SPtVxn2PxNkn66rrtUxs9iZldKelKSTr//POTaTkAIJMoxbM5ko62EGIqHtPXsAvsTxGEVkutSyqqfuIRqt/7BE2e/i5Vnvq/Vbi+OtL7Qtb5641MPAAAAOzUdsozPmMQT2xm45J+VtKr401vkzQnyePLP5H0YkkbpaC5oqy3jbafutH9KklXSVK5XN7wPgCA0Ucpnt5IOtpCqKl4TF/DDrA/RShaC1VN3/hq1VplNXWmivfeo6kbl7S4UFXh0tHdL7LOX29k4gEAAGCntlOe8b/1ut3d37jD565IusXdvxY/ztc6nvPtkhbiq8ckndfxd+dKujP+/2bbAQDbEFoWQcileJKoLEXS0RZIxQMexP4Uoaj+ZUO11k+oEa8w0NBZqrXKqr7/bzRzacqN2yXW+dscmXjIAo43AACMpu2UZyxL+hFJR+LrPyPp4+oujbgTs+oozWhme939RHz1uZI+F///iKS/MLM3SnqMpAslfVpRBtqFZnaBpOOKSj3+4i7bBAC5EWIWQaileJJcaoukox5IxQMexP4UoahrUk2d2bWtqTO1rAmN7jcZWyETD2njeAMAwOjaTtDsuyQ92d3vliQze62kv3T3X93pk5rZmZKeJemlHZv/l5lNKCqxeEf7Nne/1czeJ+nzitZUe5m7t+LHebmkRUkFSe9091t32iYAyJsQswhCLcUT4lJbmUQqHvAg9qcIxeTz96t47X1qtB4KnBUL92nieRem2CoMA5l4SBPHG4SErEkAebOdoNn5klY7rq9KetxuntTd75H0neu2vaDH/V8n6XUbbP+wpA/vpi0AkFchZhGEWoon1KW2MolUvIHjpHs0sD9FKCozBU39xBmqfeIBNe8dU/H0NU099QxVZjZaOhtAKgLsHHC8QSjImgSQR9sJmr1b0qfN7IOKssCeK+nPB9oqYJ3Q1l0CsiCpLIIs/T5DLcUT9FJbAQ6SYHOcdG8tKz8J9qcIRaEgLV5vqlZPi5OIxzjUAFkSaOeA4w1CQdYkgDwyd9/6TmZPlvTj8dWPu3t9oK0aoHK57EtLS2k3IzeSGPgJcd0lIAuS+G3x+xyOQMcSAn5h2MzCgjQ72z2AVCpJ8/OcdEv8JIaB9xgAMibQzgHHG4Ribk46dEjqHD42kw4flg4eTK9dALBbZnbU3csb3badTDNJOlPSt939z8zsHDO7wN2/nFwTEaKkOokhrrsEZEESWQT8Pocj2KW2mLaYO5Qq6i3Un0SmMpJD3Z8CwKgKtHPA8Qa7kZXKAxJZkwDyacugmZkdklSW9L2S/kzSwyRdI+lpg20aRl1SAz8hrrsEZMVuF0jn9zk8QS61FeggCTbHSXdvIf4kspiRXFBLM6pqxuuSJiVVJDGKCQCpCLhzEGT/HQOXtSzFSiV6Vkea0AAAIABJREFU/vXtqYz2MrcA0NPYNu7zXEk/K6kpSe5+p6SzBtkohKHXwE8/2usuddrJuksAksfvE7vSHiTpFMggCTbWPukulaKyLqUSJ92dQvxJdGYku7wrIzkV7ZGo2dmo1tDsbHS91UqnPXGTFhai8kcLC6k2BQCGj84B0KVzArp79wT0NLSzJufno5KM8/OUGQUQvu2UZ1x1dzczlyQzK271B4CU3ISxyv6KpvZNnTJDubKfTjSQNn6f2BWmLeYOpYp6C/EnkbmM5IzVwMzabHIAGDo6B0CXLFYeIGsSQN5sJ2j2PjP7U0lnm9mvSXqxpKsH2yyEIKmBnyTWXUKOZakYeID4fWJXGCTJJU66NxfiT6Kdkdxe+1JKOSM5YyNRGYvhAUA66BwADwq4YmliGObJHz5zDJu5+9Z3MnuWpEskmaRFd79h0A0blHK57EtLS2k3IzfaO7VQBn4wYpi+DQBAqjK3ptnCQlSSsXMkqlSKag2lMFg7NxdView8JTOLyh8dPDj05gAAgJQxjNEb70/+8JljUMzsqLuXN7xtO0GzdQ9WkHS5u78nicYNG0EzIEcyNjAGAEAetdZa2clIzthZN10VAMCwkKkxOpiAvjn6TvnDZ45B6RU027Q8o5k9XNLLJO2TdETSDfH135G0LGkkg2YAciRjJZgAAGLEJocKYwXNHJhJZw2zUxqTrRqYIa5jBwDInozNGcEWqFi6OYZ58ofPHGnotabZuyV9U9InJf2qomDZuKRL3X15CG0DgN0JuBh4e9Z+/URdk3snWUcMwGhgxAZZkKGRqIzF8LAFYv4ARhVraCIUAQ/zYBN85khDr6DZ4939ByXJzK6W9K+Sznf3u4fSMqSKE0IEIdDp25lbHwYAtiuDIzb0eZC2DMXw0AMxfwCjjEwNhCLQYR70wGeONPQKmt3f/o+7t8zsywTM8oETQgQj0Onb1ZWqasdraqxGg86N1YZqx2uqrlSzUfoKADaTsREb+jwAtiuDMX8A2DYyNRCKQId50AOfOdLQK2j2JDP7dvx/k3RGfN0kubs/fOCtQyo4IURQApy+XT9RV3O1e9C5udrU8sllgmYAsi1jIzb0eQBsV8Zi/gDQFzI1EJIAh3mwBT5zDNvYZje4e8HdHx7/O8vdT+v4PwGzgPU6IQSQvsm9kyqOF7u2FceLmtjDNEEAGdcesSmVJLPoMsURG/o8ALarHfPvRJYGgFHRztSYn5cOH44uyawHMGitlrSwIM3NRZetVtotAranV6YZcipjk8CBXQlxrZrK/oqm9k2dsqZZZT/TBAFkXMZqa9DnAbBdZGmMnhDPA4DdIFMDwDBRCh+jzNw97TYMVblc9qWlpbSbkWns1BCKTH6XEzp7b621VF2pavnksib2TKiyv6LCGD9QAOhHJo8TADKr3Y3LQMwfWwh5/04wEAAwChYWpNnZ7gmKpVKU6UrwHllgZkfdvbzRbWSa4RQZmwQO7Fjm1qpJ8Oy9MFbQzIEZ1jADkF8JjBrS5wHQD7I0RkfmzgMSEnIwEAAQFtaDxSgjaIYNcUKIEGTuAB3q2TsADFuSkxDo8wBAcDJ3HpCQ6HTC1WiYpPh04lOuatVG+nUBAMJDKXyMsrG0GwAAg5K5Bdt7nb0DALavcxKCe/ckBABA7mXuPCAh9aNraja6l9hoNl3Lt6yl1CIAADbWXg+2VJLMokvWg8WoIGgGIFiZO0CHevYOAMPGJAQAQA+ZOw9IyGRrSUXd07WtqHs08QDrtgMAsqVdCn9+Xjp8OLqknDBGBeUZAQQrc2vVtM/e15cTG/WzdwAYNmp9AAB6yNx5gJTIWpyVwvWa0rdV05SaOlNF3aMp1VQ5rSbposG0GwCAHaIUPkaVufvW9wpIuVz2pSVmYQFISftkOTNn70AYWmstVVeqqp+oa3LvpCr7KyqMpfTbSmBQDFtIcE0zAAAGLqnj1sKCWpf/kqrNH9eyJjShZVWKN6lw7XsYkQQAAOiDmR119/KGtxE0AwDsCgECpKy11tL0NdOqHa+pudpUcbyoqX1TWrxicfiBM4I5w8MkBKQsU8H6JHFcB5K3sCDNznZnSJdKUa2qfoJd9DMAAAAS0StoRnlGAMDOceKODKiuVFU7XlNjNRqIaqw2VDteU3WlqpkDQ551Xa1Gv4f2oFijEV2vVpkBnjRqfSBFmQrWd7Rp10E8juvAYPRai7Of41gm604CAACEZSztBgAARlhngMC9O0AADEn9RF3N1e6BqOZqU8snl1NoTI9BMQDB6AzWu7wrWJ+GdhBv9rpZHfrYIc1eN6vpa6bVWmv190Ac14HBaK/F2Wmna3G2J40cPBhdEjADAABIFEEzAMDOESBABkzunVRxvHsgqjhe1MSeHQxE7boxyQ2KtVpRNae5ueiy1efYd9KPA+AhmQrWK8EgHsd1YDAqlShrs1SSzKLLqaloOwAAADKF8owAgJ1rBwg612fY6axZYIcq+yua2jd1Spm0yv4UBqLag2LrS5v1OSiWVIU0Kq0Bg9EO1rfLwkopBuvVO4jXV5lajuvAYFBWEQAAYGQQNAMA7FxCAQJgNwpjBS1esajqSlXLJ5c1sWdiZ2v5JNKYZAbFkloajSXWhieR9aQwMjIVrFeCQTyO68DgsBYnAGDAWq3oXK9ej+ZCMT8D2JnUgmZmdoekuyW1JD3g7mUze5Sk90p6nKQ7JP28u3/TzEzSWyQ9R9I9kn7F3W+JH+eFkg7GD/sH7v6uYb4OYMc4kiEEzJpFRhTGCpo5MNNfRsXAGrP7QbFeFdL6edikHge9tdeTWh9AWbxikcBZoDIVrFeCQTyO6wAAACOJKiNActLONHuGu/9rx/VXSfo7d3+9mb0qvv4/JFUkXRj/m5L0NklTcZDtkKSyJJd01MyOuPs3h/kigL5xJENImDWLgGRlPkNSFdKotDYcnetJSepaTyoTgVwMRJaC9YkG8TiuAwAAjByqjADJGUu7AetcKqmdKfYuST/Xsf3PPfIpSWeb2V5J05JucPdvxIGyGyQ9e9iNBvrWeSRz7z6SAQD612pJCwvS3Fx02Wrt6CGmp6XZWenQoehyenpHD7Vr7QpppZJkFl3upEJaUo+D3nqtJzXSEvhdYXjaQbyDFx/UzIEZshwBAABypFeVEQD9STPTzCVdb2Yu6U/d/SpJ3+3uJyTJ3U+Y2aPj++6T9NWOvz0Wb9tsexczu1LSlZJ0/vnnJ/06gP5RLwsAkpNQ9m6WZuYlVSGNSmvDkdh6UllCVnxusT4fUpeVtG8AAEYIVUaA5KQZNHuau98ZB8ZuMLN/6nFf22Cb99jevSEKyF0lSeVy+ZTbgaHjSAYAyUko2pW1+QxJVUij0trgJbaeVJZkKYqMoWF9PqSOgD0AADvSrjKy/hBKlRGgf6mVZ3T3O+PLr0v6oKSLJH0tLruo+PLr8d2PSTqv48/PlXRnj+1AtlEvCwCSk1AdivZ8hk7MZ8B2tNeTmr9sXoefcVjzl82PfpCB+i651Lk+n8u71ucDhoIy9gAA7Ei7ysj8vHT4cHTJnBNgZ1LJNDOzoqQxd787/v8lkg5LOiLphZJeH19+KP6TI5JebmbXSpqS9K24fOOipP9pZo+M73eJpFcP8aUAO0O9LOAUlIPCjiWUvcvMPOxGez2pmQOBZGGRFT88GSpF12t9vtS+2xl6fzAEWUv7BgBghFBlBEhGWuUZv1vSB82s3Ya/cPe/NbObJb3PzF4i6SuSnh/f/8OSniNpRdI9kl4kSe7+DTObk3RzfL/D7v6N4b0M5FUi5+4cyXpifCRfKAeFXUko2sV8BoRk1xMRiCIPR4Kl6JLoO2VufT5K9eUPAftc4twPAABkibnna4mvcrnsS0tLaTcDI4xz98HjPc6fhdsXNHvdbNcgXWm8pPnL5sPJ2sBgtUdbiHYByU1E4Hc1eAsL0uxsd4CgVIrq6fQxsSqpvlPmJrEk9P5ghHAikDt85AAAIA1mdtTdyxvdltqaZsCoosz+4PEe50+vclDAtrSzdw8ejC4ZZUGOJbYuFb+rwUto7bik+k6ZW5+PtfXyhwVZcodzPwAAkDUEzYA+ce4+eLzH+dMuB9Up1XJQADDCmIgwQtql6DrtoBRdkn2n9vp8By8+qJkDM+mWSU7o/cGIIWCfK5z7AQCArCFoBvSJc/fB4z3On8r+iqb2Tak0XpLJVBovaWrflCr7WTsHAPrFRIQR0l47rlSSzKLLHawdF2zfKaH3B0B2Bbv/AgAAI4s1zYA+UXN98HiP86m11lJ1parlk8ua2DOhyv5KurPbs4YV0gFsU+bWpUJvCawdF3TfibX1gKAFvf8CAACZ1WtNM4JmwA5w7j54vMdAB0YTAPSJiQhDkLHJDPSdAIwq9l8AAGDYCJp1IGgGABg5CwvS7Gy0MnpbqSTNz0drfQA9tIMn9RN1Te6dJHgCJIHJDFti37M53hsAAAAgXb2CZqcNuzEAAKBPvVZIJ2iGHhIt05exrBogVdVqFDBrT2ZoNKLr1Sr7ZVEitBfeG2QBh3QAAIDNETQDkChmzgID0F4hvTPTjBXSsQ3Vlapqx2tqrEbfncZqQ7XjNVVXqpo50MfAPlk1QDcmM/SU2L4nQLw3SBuHdAAAgN7G0m4AgHC0Z87OXjerQx87pNnrZjV9zbRaa620mwaMtkolGs0olSSz6HJqKtoO9FA/UVdztXtgv7na1PLJ5f4eqDOrxr07qwbIo/Zkhk5MZnhQYvueAPHeIG0c0gEAAHojaAYgMZ0zZ13eNXMWwC4UCtH03/l56fDh6JLpwNiGyb2TKo53D+wXx4ua2NPnwH69rtY9DS0ckOYulhYOSK17GlFWTUparWi5v7m56LLF/AwME5MZekps3xMg3pvRE9rxpleiLAAAACjPCCBBvWbOUm4G2KVCISr5Rdkv9KGyv6KpfVOnrJ1T2d/fwH5r4oc0/cKCantaaj5MKt4vTZ0saPFJP6g0QreUlkLq2pMZqtVopHligkWBOiS17wkR781oCfF4Q9VvAACA3giaAUhMe+Zse40GiZmzAJCmwlhBi1csqrpS1fLJZU3smdjRWpPVC6XauVIj/rPGd0TXqxdKaYRxO0tLSd2lpYgrY2iYzLCppPY9IeK9GS0hHm/aibLrA4EkygIAAEQImmGgWmstVVeqqp+oa3LvJCeEgWPmLABkT2GsoJkDM7vK+K1/7TNqFta6tjULa1r++mc1832X9vVYSfQNepWWGtVBTCA0Sex7QsV7MzpCPN6QKAsAANAbQTMMTGutpelrpk8JoCxesUjgLFDMnAWAMCWVSZxU34DSUgCAYQj1eEOiLAAAwObG0m4AwlVdqap2vKbGakMuV2O1odrxmqor1bSbhgFqz5w9ePFBzRyY2XHArLXW0sLtC5q7cU4Lty+otTbiK24DwAhrZxKXxksymUrjpR1lEifVN2iXliqVJLPoktJSAICkcbwBAADIHzLNMDD1E3U1V7trWTRXm1o+uUwpEvREliIAZEtSmcRJ9Q0oLQUAGAaONwAAAPlD0AwDk1QpJ+RPZyaCpK5MBAKuAJCOJNbgSbJvQGkp7BRr7gLoB8cbAACAfCFohoFpl3Jany3Ubykn5A9ZiltrtaIZr/V6tNYCM14BjIIs9g0IoAxBhg5aZLMDAAAAAHohaIaBSaqUE/KHLMXeWi1pelqq1aRmM1qMfGoqKh1D4AxAlmWtb0AAZQgydtAimx0AAAAA0MtY2g1A2NqlnA5efFAzB2YYgMK2tDMRSuMlmUyl8VLqmQhZUq1GY4+NhuQeXdZq0XYAyLos9Q06Aygu7wqgICEZO2j1ymYHAAAAAIBMMwCZk7VMhKyp16PJ+p2azWhxctZaAIDtoxzwEGTsoEU2O5B9lM0FAABAmgiaIV8ytKYGemtnIjBoearJyai6VeOh8T4Vi9IE433JYn8BBC/RAAr7jI1l7KCVxXX1EsN3EAGgbC4AAEB/OA1IHkEz5EfG1tQAdqpSib6667/KlQDG+zKD/QWQC4kFUNhnbC5jB61gs9n5DiIQrDsIYJQxcA1g2DgNGAyCZsiPzjU1pO41NahphxFSKEQHv2o1qm41MUFnPHHsL4BcSCyAwj5jcxk8aAWZzc53EIGgbC6AUcXANYA0cBowGATNMBqSmK6TsTU1gsXUqqEoFKKvLV/dAWF/AeRGIgEU9hm9cdAaPL6DCATrDgIYVQxcA0gDpwGDQdAM2ZfUdJ2MrakRJKZWIRTsLwD0g30G0sZ3EIEIet1BAF1Cm2/LwDWANHAaMBhjaTcA2FLndB337uk6/WivqVEqSWbRJQtBJSupzwpIG/sLAP1gn4G08R1EINplc+cvm9fhZxzW/GXzWrxicfTXHQTQpT3fdnZWOnQoupyejraPqvbAdScGrgEMGqcBg0GmGbIvqek6GVxTIzhMrUIo2F8A6Af7jJ5Cm0meSXwHEZAg1x0E0CXEUobtgev1hXcYuAYwSJwGDAZBM2RfknmmrKkxWOQEIyTsLwD0g33GhqjcPER8BwEAIyLE+bYMXANIC6cByRt6eUYzO8/MPmpmt5nZrWb2ynj7a83suJktx/+e0/E3rzazFTP7gplNd2x/drxtxcxeNezXgm1otaSFBWluLrrcSa49eaa9JfEeJ4XPCgAAdKByMwAAWC/UUobtgeuDB6NLAmYAMJrSyDR7QNJvufstZnaWpKNmdkN825vc/Q2ddzazJ0q6XNL3S3qMpI+Y2YH45rdKepakY5JuNrMj7v75obwKbC2pqcVM19lc1qZv81kBmddaa6m6UlX9RF2TeydV2V9hnZAOvD9AskKcSQ7sVrAlS4N9YQCSRilDAECWDT1o5u4nJJ2I/3+3md0maV+PP7lU0rXufp+kL5vZiqSL4ttW3P1LkmRm18b3JWiWFUkWqSbPdGNZLATOZwVkVmutpel3X6LaVz6h5tq9Ko6drqnzn6rFF1xPYEjx+3PNtGrHa2quNlUcL2pq35QWr1jk/cGWGCveGJWbgW5Zm/OWmGBfGIBBYL4tACDLhl6esZOZPU7SpKRavOnlZvYZM3unmT0y3rZP0lc7/uxYvG2z7Rs9z5VmtmRmS3fddVeCrwA99ZpajGTwHgPoQ/X2BdW+eKMaa/fKJTXW7lXtizeqevtC2k3LhOpKVbXjNTVWG3K5GqsN1Y7XVF2hjhx6a48Vz85Khw5Fl9PT6VZMzgoqNwPdgi1ZGuwLAzAolDIEAGRVakEzMytJuk7Sb7r7tyW9TdL3SJpQlIn2J+27bvDn3mP7qRvdr3L3sruXzznnnF23HdsUapHqLOE9BtCH+k1/qaZ1j+I3raXlm96fUouypX6iruZq90SE5mpTyyeZiIDeGCveXHsm+fy8dPhwdEniCfIs2Dlvwb4wAAAA5E0qQTMze5iigNl73P0DkuTuX3P3lruvSXq7HirBeEzSeR1/fq6kO3tsR1YwtXjweI+B3GittbRw+4LmbpzTwu0Laq31n8IyeUIq3t+9rXi/NHEyoUaOuMm9kyqOd09EKI4XNbGHiQjojbHi3kKdSd5qSQsL0txcdElmIbYj2Dlvwb4wAAAA5M3Q1zQzM5P0Dkm3ufsbO7bvjdc7k6TnSvpc/P8jkv7CzN4o6TGSLpT0aUWZZhea2QWSjku6XNIvDudVYFsoUj14vMdA5iWxzlFSa21VJp+vqQ9eq9qelpoPiwJmUycLqjz3eX2+qjBV9lc0tW/qlPe5sp+JCOiNdbvyh+WbsFPtOW/rvzsjP+ct2BcGAACAvDH3DSsaDu4JzX5M0k2SPitpLd78GkmzikozuqQ7JL20HUQzs9+V9GJJDygq51iNtz9H0pslFSS9091ft9Xzl8tlX1paSvIlAQCwoaQGVRduX9DsdbNqrD40Il8aL2n+snnNHJjpq0Gt6UtUvesTWj77Xk38++mqnPNUFRavZ5Q31lprqbpS1fLJZU3smVBlf6WvwGSyjUkg4oqhIICSPwsL0dp1nYHSUikqPznTx24Z+dTevQc35y3YFwYASAKnNwCyxMyOunt5w9uGHTRLG0EzhKY9wFs/Udfk3sl0B3gBdElqUHXuxjkd+tghecfSnSbT4Wcc1sGLD/bXKAa0RgNRmJHDTytf5uakQ4eiNezazKJ12w72uVsGAAAIHac3ALKmV9Bs6OUZASQnqZJtAAaj1zpH/QTN2mttdWaa7XitrfbiQqRCZFu1Gp1RtiOujUZ0vVrls8soflr5QklOAACQdVnK7OL0BsAoGUu7AcAwhbZge3WlqtrxmhqrDblcjdWGasdrqq5U024aAD00qNppJ4Oq7bW2SuMlmUyl8RJrbYWuV8QVQOrayzeVSlGGWanE8k0YYaGdJGFo+OoA2dXO7JqdjbLjZ2ej62n9TkM+vWFfCISHTDPkRoip4PUTdTVXu3sdzdWmlk8u97fOEYCBqFSki6Za+sRdVd37yLpO/+akLjqnokqlv51OYaygxSsWs7PWFgaPNBbgVBmaLl0oRH1ISnJi5IV4koSh4KsDZFvWMrtCPb1hXwiEiaAZciNrHYYkJFqyDUDyrCW9YFr6Sk1aa0pjRen8KckWJfUfOJs5MENAPC/aaSzrz75IY0FeZXBEgpKcCEK1qtanbla1+ROqa1KTjboqn7pJhVE+ScJQhHh+DYQkqaUCkhLq6Q37QiBMlGdEboSYCk7JNiDbqitVffrOmu5da0hy3bvW0KfvpIQqtqGdxjI/Lx0+HF0yXTEfqO+ysc4RCffuEQkAO9Y6uqzp5nWa1bwO6bWa1bymm9epdcs/pt204IS2ew/x/BoISVJLBSQl1NMb9oVAmMg0Q26EmApOyTYg2yihil0hjSV/MphNlRlZmy4NBKLaukQ1PVENlSRJDZ2lmp6i6gMPF7+sWAKlYUPcvYd4fg2EJIuZXSGe3rAvBMJE0Ay5kcUOQxIo2QZkFyVUAfSF+i6bY0QCGIh6oax14Wg1daaWTysTNJMSi3aFuHsP9fwaCAXrrw4H+0IgTATNkBt0GAAMW7uEau14Tc3VporjRUqoAtgc2VSbY0QCGIjJHx5TseTr4tGmiSdbeo3KkoSiXSHu3jm/BrIvxMyurGFfCISJoBlyhQ4DgGGihCqAvpBNtTlGJICBiOLRti4ebcSj2xKKdoW6e+f8GgDYFwIhMndPuw1DVS6XfWlpKe1mAAAAAN1CXPQGQOa1l+wiHr2BhQVpdrY72lUqSfPzfY2OsnsHAADIFjM76u7lDW8jaAYAAABkBKPXAJAdCUa72L0DAABkB0GzDgTNAAAAAADAthDtAgAACE6voBlrmgEAAAAAAGyExWoAAAByZSztBgAAAAAAAAAAAABpI9MMAAAAAAAgL9olJ+t1aXKSkpMAAAAdCJoBAAAAAADkQaslTU9LtZrUbErFojQ1JS0uEjgDAAAQ5RkBANhQqyUtLEhzc9Flq5V2iwAAAIBdqlajgFmjIblHl7VatB0AAABkmgEAsB4TcAEAABCkej3q4HZqNqXlZWlmJp02AQAAZAiZZgAArMMEXAAAAARpcjKaEdapWJQmJtJpDwAAQMYQNAMAYJ1eE3ABAACAkVWpRCUUSiXJLLqcmoq294t65gAAIECUZwQAYJ32BNxG46FtTMAFAADAyCsUoprj1Wo0I2xiIgqY9VuDnHrmAAAgUGSaAQCwTpITcAEAAIBMKRSi9csOHowudxLkop45AAAIFJlmAACsk9QEXAAAACBIveqZz8yk0yYAAIAEEDQDAGAD7Qm4nPMDAAAA61DPHAAABIryjAAAAAAAANg+6pkDAIBAkWkGAAAAAEhUqxWVOa7Xo4QUyhwDgaGeOQAACBRBMwAA0LfWWkvVlarqJ+qa3Dupyv6KCmMMkoSMAXAA29VqSdPTUq0WLXFULEYJKIuL7DeAoFDPHAAABIigGQAA6EtrraXpa6ZVO15Tc7Wp4nhRU/umtHjFIoGzQDEADqAf1Wq0v2gvddRoRNerVcbWAQAAAGQba5oBALCB1lpLC7cvaO7GOS3cvqDWWivtJmVGdaWq2vGaGqsNuVyN1YZqx2uqrlTTbhoGpHMA3L17ABwA1qvXowB7p2YzquAGAAAAAFk28plmZvZsSW+RVJB0tbu/PuUmBSFrZbcoCTV4WfvMMTpC/H2SSdVb/URdzdXu0dDmalPLJ5c1c4AUghD1GgAnawTYnRD7YJOTUUZqO9NMiq5PTKTXJmwuqe9gUn3CEPuWwG7wm9gc7w2AfrDPwHaNdNDMzAqS3irpWZKOSbrZzI64++fTbdloy9pgMSWhBi9rnzlGR6i/z85MKkldmVQEhaTJvZMqjhcffH8kqThe1MQeRkNDxQA4MBih9sEqlag/sL5/UKmk3TKsl9R3MKk+Yah9S2Cn+E1sjvcGQD/YZ6Afo16e8SJJK+7+JXdflXStpEtTbtPIy1rZLUpCDV7WPnOMjlB/n70yqSBV9lc0tW9KpfGSTKbSeElT+6ZU2c9oaKjaA+ClkmQWXTIADuxeqH2wQiEagJiflw4fji4ZkMimpL6DSfUJQ+1bAjvFb2JzvDcA+sE+A/0Y9aDZPklf7bh+LN7WxcyuNLMlM1u66667hta4UZW1wWLWRBi8rH3mGB2h/j7bmVSdyKR6SGGsoMUrFjV/2bwOP+Ow5i+bH/msCPTGADgwGCH3wQqFqHzrwYPRJfuLbErqO5hUnzDUviWwU/wmNsd7A6Af7DPQj5EuzyjJNtjmp2xwv0rSVZJULpdPuR3dslZ2i5JQg5e1zxyjI9TfZzuTan2pIjKpHlIYK2jmwAzlKnOkPQDOGmZAcuiDIW1JfQeT6hOG2rcEdorfxOZ4bwD0g30G+jHqmWbHJJ3Xcf1cSXem1JZgZK3sFiWhBi9rnzlGR6i/TzKpAADDQB8MaUvqO5hUnzDUviWwU/wmNsd7A6Af7DPQD3Mf3cQrMztN0u2SninpuKT7ocXhAAAJwElEQVSbJf2iu9+62d+Uy2VfWloaUgtHV2utpepKVcsnlzWxZ0KV/ZVUB4tbrajG7PJyNAOgUqHES9Ky9pljdPD7BABg5+iDIW1JfQeT6hPStwS68ZvYHO8NgH6wz0AnMzvq7uUNbxvloJkkmdlzJL1ZUkHSO939db3uT9AMAAAAAAAAAAAgn3oFzUZ9TTO5+4clfTjtdgAAAAAAAAAAAGB0jfqaZgAAAAAAAAAAAMCuETQDAAAAAAAAAABA7hE0AwAAAAAAAAAAQO4RNAMAAAAAAAAAAEDuETQDAAAAAAAAAABA7hE0AwAAAAAAAAAAQO4RNAMAAAAAAAAAAEDuETQDAAAAAAAAAABA7hE0AwAAAAAAAAAAQO6Zu6fdhqEys7sk/Uva7Rgh3yXpX9NuBADgQeyXASBb2C8DQLawXwaAbGG/jCx6rLufs9ENuQuaoT9mtuTu5bTbAQCIsF8GgGxhvwwA2cJ+GQCyhf0yRg3lGQEAAAAAAAAAAJB7BM0AAAAAAAAAAACQewTNsJWr0m4AAKAL+2UAyBb2ywCQLeyXASBb2C9jpLCmGQAAAAAAAAAAAHKPTDMAAAAAAAAAAADkHkEzbMjMnm1mXzCzFTN7VdrtAYC8MbPzzOyjZnabmd1qZq+Mtz/KzG4ws3+OLx+ZdlsBIE/MrGBmdTNbiK9fYGa1eL/8XjMbT7uNAJAnZna2mb3fzP4p7jv/KH1mAEiPmf3XeBzjc2Y2b2an02fGKCFohlOYWUHSWyVVJD1R0qyZPTHdVgFA7jwg6bfc/QmSniLpZfG++FWS/s7dL5T0d/F1AMDwvFLSbR3X/0jSm+L98jclvSSVVgFAfr1F0t+6+/dJepKifTR9ZgBIgZntk/QKSWV3/wFJBUmXiz4zRghBM2zkIkkr7v4ld1+VdK2kS1NuEwDkirufcPdb4v/frejkf5+i/fG74ru9S9LPpdNCAMgfMztX0k9Lujq+bpJ+UtL747uwXwaAITKzh0u6WNI7JMndV93930WfGQDSdJqkM8zsNElnSjoh+swYIQTNsJF9kr7acf1YvA0AkAIze5ykSUk1Sd/t7iekKLAm6dHptQwAcufNkv67pLX4+ndK+nd3fyC+Tr8ZAIbr8ZLukvRncencq82sKPrMAJAKdz8u6Q2SvqIoWPYtSUdFnxkjhKAZNmIbbPOhtwIAIDMrSbpO0m+6+7fTbg8A5JWZzUj6ursf7dy8wV3pNwPA8Jwm6cmS3ubuk5KaohQjAKQmXkPyUkkXSHqMpKKiJYDWo8+MzCJoho0ck3Rex/VzJd2ZUlsAILfM7GGKAmbvcfcPxJu/ZmZ749v3Svp6Wu0DgJx5mqSfNbM7FJUv/0lFmWdnx6VnJPrNADBsxyQdc/dafP39ioJo9JkBIB0/JenL7n6Xu98v6QOSnir6zBghBM2wkZslXWhmF5jZuKLFGo+k3CYAyJV4nZx3SLrN3d/YcdMRSS+M//9CSR8adtsAII/c/dXufq67P05R//jv3f2XJH1U0vPiu7FfBoAhcveTkr5qZt8bb3qmpM+LPjMApOUrkp5iZmfG4xrt/TJ9ZowMcycTEqcys+comjlbkPROd39dyk0CgFwxsx+TdJOkz+qhtXNeo2hds/dJOl9RZ/T57v6NVBoJADllZk+X9NvuPmNmj1eUefYoSXVJV7j7fWm2DwDyxMwmJF0taVzSlyS9SNEkcfrMAJACM/t9Sb8g6QFF/eNfVbSGGX1mjASCZgAAAAAAAAAAAMg9yjMCAAAAAAAAAAAg9wiaAQAAAAAAAAAAIPcImgEAAAAAAAAAACD3CJoBAAAAAAAAAAAg9wiaAQAAAAAAAAAAIPcImgEAAADAAJhZy8yWzexzZvbXZnZ2Btr0mhSf+1fM7P+k9fwAAAAAsBWCZgAAAAAwGP/h7hPu/gOSviHpZWk3SFJqQTMAAAAAyDqCZgAAAAAweJ+UtK99xcx+x8xuNrPPmNnvd2z/XTP7gpl9xMzmzey34+0fM7Ny/P/vMrM74v8XzOyPOx7rpfH2vWb28Y5Mtx83s9dLOiPe9h4zK5rZ35jZP8b3+YX1jY6f903xY91mZj9iZh8ws382sz/ouN9fmdlRM7vVzK7s2P4iM7vdzG6U9LSO7eeY2XVxu282s6cJAAAAAFJ2WtoNAAAAAICQmVlB0jMlvSO+fomkCyVdJMkkHTGziyU1JV0uaVLRudotko5u8fAvkfQtd/8RM/sOSf/PzK6X9J8kLbr76+LnP9PdbzKzl7v7RNyOyyTd6e4/HV9/xCbPseruF5vZKyV9SNIPK8qc+6KZvcnd/03Si939G2Z2hqSbzew6SeOSfj++/7ckfVRSPX7Mt0h6k7v/g5mdL2lR0hO2834CAAAAwKAQNAMAAACAwTjDzJYlPU5R8OuGePsl8b92AKmkKIh2lqQPuvs9kmRmR7bxHJdI+iEze158/RHxY90s6Z1m9jBJf+Xuyxv87WclvcHM/kjSgrvftMlzHOm4/63ufiJu35cknSfp3yS9wsyeG9/vvLgNeyR9zN3viu//XkkH4vv8lKQnmln7OR5uZme5+93beM0AAAAAMBCUZwQAAACAwfiPOKvrsYqyrtprmpmkP4zXO5tw9/3u/o74Nt/ksR7QQ+dvp3dsN0n/peOxLnD3693945IulnRc0rvN7JfXP6C7364oC+yzkv7QzH5vk+e+L75c6/h/+/ppZvZ0RUGwH3X3JykKBrbbuNnrGYvv3273PgJmAAAAANJG0AwAAAAABsjdvyXpFZJ+O878WpT0YjMrSZKZ7TOzR0v6uKTnmtkZZnaWpJ/peJg7FAW4JOl5HdsXJf1G/LgyswPxWmWPlfR1d3+7orKQT47vf3/HfR8j6R53v0bSGzru069HSPqmu99jZt8n6Snx9pqkp5vZd8bP+fyOv7le0svbV8xsYofPDQAAAACJoTwjAAAAAAyYu9fN7B8lXe7u7zazJ0j6ZFyesCHpCne/JS5huCzpXyR1lkt8g6T3mdkLJP19x/arFZV/vMWiB7tL0s9Jerqk3zGz++PHb2eaXSXpM2Z2i6Q/l/THZrYm6X5Jv7HDl/e3kn7dzD4j6QuSPhW/5hNm9lpJn5R0QtEabYX4b14h6a3x35ymKGD46zt8fgAAAABIhLlvVi0DAAAAAJCWOODUcPc3pN0WAAAAAMgDyjMCAAAAAAAAAAAg98g0AwAAAAAAAAAAQO6RaQYAAAAAAAAAAIDcI2gGAAAAAAAAAACA3CNoBgAAAAAAAAAAgNwjaAYAAAAAAAAAAIDcI2gGAAAAAAAAAACA3CNoBgAAAAAAAAAAgNz7/yfnauRJYaAwAAAAAElFTkSuQmCC\n"}]},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173577_1190291426","id":"paragraph_1591860123109_1248831991","dateCreated":"2020-08-20 21:16:13.577","status":"READY"},{"text":"%python.ipython\n","user":"anonymous","dateUpdated":"2020-08-20 21:16:13.577","config":{},"settings":{"params":{},"forms":{}},"apps":[],"runtimeInfos":{},"progressUpdateIntervalMs":500,"jobName":"paragraph_1597958173577_538284345","id":"paragraph_1597047441935_258792906","dateCreated":"2020-08-20 21:16:13.577","status":"READY"}],"name":"Log Analysis-Zeppelin","id":"2FJF9WE51","defaultInterpreterGroup":"spark","version":"0.9.0-preview2","noteParams":{},"noteForms":{},"angularObjects":{},"config":{"isZeppelinNotebookCronEnable":false},"info":{}}
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/OpenSearch_Dashboards_Embeddable_Documentation.md b/dashboards-observability/public/components/notebooks/docs/poc/OpenSearch_Dashboards_Embeddable_Documentation.md
new file mode 100644
index 000000000..a7ac63ece
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/OpenSearch_Dashboards_Embeddable_Documentation.md
@@ -0,0 +1,55 @@
+# OpenSearch Dashboards Embeddable API & Embedding Visualizations
+
+**NOTE:** The embeddable API and Visualizations have been in high flux for past 6 releases 7.4→7.9 versions in OpenSearch Dashboards
+
+## **In Version 7.5 and older**
+
+1. [Elastic blog](https://www.elastic.co/blog/developing-new-kibana-visualizations) on embedding Visualization
+2. [Test Plugin](https://github.com/elastic/kibana/tree/7.5/test/plugin_functional/plugins/kbn_tp_visualize_embedding) for OpenSearch Dashboards Visualization embedding
+
+**Between 7.6 and 7.8 - Embeddable API has changed at a high frequency, better to use it from 7.9**
+
+## **Embeddable API - Situation post 7.9 update**
+
+- Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable _containers_.
+- Containers are a special type of embeddable that can contain nested embeddables. Embeddables can be dynamically added to embeddable _containers_. _Currently only dashboard uses this interface._
+
+![Embeddable API](../dev/images/Embeddable_API.png)
+
+* [Source](https://github.com/elastic/kibana/issues/19875)
+* [Code](https://github.com/elastic/kibana/tree/master/src/plugins/embeddable)
+* [README](https://github.com/elastic/kibana/blob/master/src/plugins/embeddable/README.md)
+
+1. Visualizations, Saved Search and Dashboard embeddable are part of this API now.
+2. Embeddable Factory allows to create objects:
+ 1. with “.create()” menthod → needs input of data/source/query/time range explicitly
+ 2. with “.createFromSavedObject()” method → either inherits values from containers or takes from explicit input provided
+3. Each of the above has a implementation has to inherit an embeddable & Factory API like:
+ 1. [Viz. Embeddable](https://github.com/elastic/kibana/blob/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts) & [Factory](https://github.com/elastic/kibana/blob/master/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx)
+ 2. [Creating Custom Embeddable Example](https://github.com/elastic/kibana/blob/master/examples/embeddable_examples/public/multi_task_todo/multi_task_todo_embeddable.tsx) & [Factory](https://github.com/elastic/kibana/blob/master/examples/embeddable_examples/public/multi_task_todo/multi_task_todo_embeddable_factory.ts) by Value
+ 3. [Creating Custom Embeddable Example](https://github.com/elastic/kibana/blob/master/examples/embeddable_examples/public/todo/todo_ref_embeddable.tsx) & [Factory](https://github.com/elastic/kibana/blob/master/examples/embeddable_examples/public/todo/todo_ref_embeddable_factory.tsx) by reference
+4. [Visualizations Embeddable API Code](https://github.com/streamich/kibana/tree/master/src/plugins/visualizations/public/embeddable)
+5. [Dashboard Container](https://github.com/elastic/kibana/blob/master/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx) is exposed as an embeddable - to have multiple embeddable in a GRID like structure just like the Dashboard Plugin.
+
+**Embeddable Examples**
+
+- Examples folder in OpenSearch Dashboards has all the usage samples for new APIs
+- Use to create new embeddable objects
+- [Embeddable Examples](https://github.com/elastic/kibana/tree/master/examples/embeddable_examples) shows how to create new embeddable inheriting the API
+- [Embeddable Explorer](https://github.com/elastic/kibana/tree/master/examples/embeddable_explorer)shows usage of these embeddable examples in a Panel Container
+- [Dashboard Embeddable](https://github.com/elastic/kibana/tree/master/examples/dashboard_embeddable_examples) shows usage of these embeddable examples in a Dashboard Container
+
+**Embeddable Renderer**
+
+- The OpenSearch Dashboards react Element/Prop to create new embeddable objects: [Code](https://github.com/elastic/kibana/blob/master/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.tsx)
+- Embeddable container use the renderer to create/update each child(an embeddable object)
+ - [Example Dashboard Container](https://github.com/elastic/kibana/blob/master/src/plugins/dashboard/public/application/embeddable/dashboard_container_by_value_renderer.tsx)
+ - [Example of Static Embedding](https://github.com/elastic/kibana/blob/master/examples/embeddable_explorer/public/hello_world_embeddable_example.tsx#L59) (without factory)
+ - [Example of Embedding with factory.create() method](https://github.com/elastic/kibana/blob/master/examples/embeddable_explorer/public/hello_world_embeddable_example.tsx#L73) (with factory)
+
+## Embedding Visualizations in Notebooks Plugin
+
+- Notebooks use embeddable API with dashboard containers for embedding visualizations
+- Dashboard containers allow loading saved objects by Id
+- Notebook paragraphs store the dashboard container object as json string in input cells
+- For storing visualizations in Zeppelin input cells, the json string is stored with a prefix “%sh #{JSON_STRING}”. Making the Json object look like a comment so that, it doesn’t interrupt running the whole notebook.
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/Zeppelin_OpenSearch_Storage.md b/dashboards-observability/public/components/notebooks/docs/poc/Zeppelin_OpenSearch_Storage.md
new file mode 100644
index 000000000..256a9ff48
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/Zeppelin_OpenSearch_Storage.md
@@ -0,0 +1,67 @@
+# **Custom OpenSearch Storage in Zeppelin**
+
+### **Requirement:**
+
+- Use Zeppelin as a backend service for OpenSearch Dashboards Notebooks and store notebooks as OpenSearch indices
+- Use Zeppelin’s storage adaptor interface and implement a new storage adaptor using OpenSearch Client
+
+### **Design:**
+
+- [“Transport client API“](https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html) is getting deprecated in favor of high level client.
+- Finalized, [“High level client API”](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.8/java-rest-high.html) for ease of use and minimal operations needed for Adaptor.
+- Notebooks will be indexed as* .notebooks/\_doc/{Unique_id} →* Unique ID is generated by zeppelin
+
+### **Design Details:**
+
+1. Implements the interface common for all Zeppelin Storage adaptors
+2. Implementation of functions in OpenSearch Zeppelin storage adaptor:
+
+ - Init - Get all config params
+ - List - List all notebooks
+ - Get - fetch a notebook
+ - save - save a notebook
+ - remove - a note
+ - close - client connection
+ - Upgrade client to Https requests - Done using keystore
+
+### **Usage:**
+
+1. POC for OpenSearch adapter is stored in branch 'zeppelin-opensearch' of dashboards-notebooks
+```
+git checkout zeppelin-opensearch
+```
+2. Clone Apache Zeppelin and checkout to 'v0.9.0-preview2' branch in a separate folder
+```
+cd /your/folder/
+git clone https://github.com/apache/zeppelin.git
+cd zeppelin
+git checkout v0.9.0-preview2
+```
+3. Apply patch from dashboards-notebooks
+```
+git apply /path/to/zeppelin-patch
+```
+4. Once, in this branch copy "opensearch" storage adaptor to your zeppelin files
+```
+cp -r /path/to/dashboards-notebooks/zeppelin/zeppelin-plugins/notebookrepo/opensearch path/to/your/zeppelin
+```
+4. Add OpenSearch storage property in zeppelin config file "conf/zeppelin-site.xml" and you should comment default git storage
+```
+
+ zeppelin.notebook.storage
+ org.apache.zeppelin.notebook.repo.OpenSearchNotebookRepo
+ versioned notebook persistence layer implementation
+
+
+
+```
+5. [Build Zeppelin](https://zeppelin.apache.org/docs/0.9.0/setup/basics/how_to_build.html) using Open-JDK 8
+```
+ mvn clean package -DskipTests
+```
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/docs/Zeppelin_OpenSearch_Storage.md b/dashboards-observability/public/components/notebooks/docs/poc/docs/Zeppelin_OpenSearch_Storage.md
new file mode 100644
index 000000000..2449ca672
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/docs/Zeppelin_OpenSearch_Storage.md
@@ -0,0 +1,73 @@
+# **Custom OpenSearch Storage in Zeppelin**
+
+### **Requirement:**
+
+- Use Zeppelin as a backend service for OpenSearch Dashboards Notebooks and store notebooks as indices
+- Use Zeppelin’s storage adaptor interface and implement a new storage adaptor using Elasticsearch Client
+
+### **Design:**
+
+- [“Transport client API“](https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html) is getting deprecated in favor of high level client.
+- Finalized, [“High level client API”](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.8/java-rest-high.html) for ease of use and minimal operations needed for Adaptor.
+- Notebooks will be indexed as* .notebooks/\_doc/{Unique_id} →* Unique ID is generated by zeppelin
+
+### **Design Details:**
+
+1. Implements the interface common for all Zeppelin Storage adaptors
+2. Implementation of functions in OpenSearch Zeppelin storage adaptor:
+
+ - Init - Get all config params
+ - List - List all notebooks
+ - Get - fetch a notebook
+ - save - save a notebook
+ - remove - a note
+ - close - client connection
+ - Upgrade client to Https requests - Done using keystore
+
+### **Usage:**
+
+
+1. Clone [dashbaords-notebooks](https://github.com/opensearch-project/dashboards-notebooks/) repository
+
+2. Clone [Apache Zeppelin](https://github.com/apache/zeppelin) and checkout to 'v0.9.0-preview2' branch in a separate folder
+
+```
+cd zeppelin
+git checkout v0.9.0-preview2
+```
+
+3. Apply patch from dashboards-notebooks
+
+```
+git apply /path/to/dashboards-notebooks/poc/zeppelin-patch
+```
+
+4. Once, in this branch copy "opensearch" storage adaptor to your zeppelin files
+
+```
+cp -r /path/to/dashboards-notebooks/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch path/to/your/zeppelin/zeppelin-plugins/notebookrepo/.
+```
+
+5. Add OpenSearch storage property in zeppelin config file "conf/zeppelin-site.xml" and you should comment default git storage
+
+```
+
+ zeppelin.notebook.storage
+ org.apache.zeppelin.notebook.repo.OpenSearchNotebookRepo
+ versioned notebook persistence layer implementation
+
+
+
+```
+
+6. [Build Zeppelin](https://zeppelin.apache.org/docs/0.9.0/setup/basics/how_to_build.html) using Open-JDK 8
+
+```
+ mvn clean package -DskipTests
+```
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/zeppelin-patch b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin-patch
new file mode 100644
index 000000000..e6f861187
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin-patch
@@ -0,0 +1,3057 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+diff --git a/elasticsearch/pom.xml b/elasticsearch/pom.xml
+index 13bc6d469..bbdde076a 100644
+--- a/elasticsearch/pom.xml
++++ b/elasticsearch/pom.xml
+@@ -23,25 +23,26 @@
+
+ zeppelin-interpreter-parent
+ org.apache.zeppelin
+- 0.9.0-preview2
++ 0.9.0-SNAPSHOT
+ ../zeppelin-interpreter-parent/pom.xml
+
+
+ zeppelin-elasticsearch
+ jar
+- 0.9.0-preview2
++ 0.9.0-SNAPSHOT
+ Zeppelin: Elasticsearch interpreter
+
+
+ elasticsearch
+- 2.4.3
+- 4.0.2
++ 7.8.0
++ 4.1.4
+ 18.0
+ 0.1.6
+ 1.4.9
+
+
+
++
+
+ org.opensearch
+ elasticsearch
+@@ -58,11 +59,11 @@
+ commons-lang3
+
+
+-
+- org.apache.httpcomponents
+- httpasyncclient
+- ${httpasyncclient.version}
+-
++
++
++
++
++
+
+
+ com.google.guava
+diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
+index 45b37c4eb..d7987a011 100644
+--- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
++++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreter.java
+@@ -21,19 +21,6 @@ import com.google.gson.Gson;
+ import com.google.gson.GsonBuilder;
+ import com.google.gson.JsonObject;
+
+-import org.apache.commons.lang3.StringUtils;
+-import org.opensearch.common.xcontent.XContentBuilder;
+-import org.opensearch.common.xcontent.XContentFactory;
+-import org.opensearch.common.xcontent.XContentHelper;
+-import org.opensearch.search.aggregations.Aggregation;
+-import org.opensearch.search.aggregations.Aggregations;
+-import org.opensearch.search.aggregations.InternalMultiBucketAggregation;
+-import org.opensearch.search.aggregations.bucket.InternalSingleBucketAggregation;
+-import org.opensearch.search.aggregations.bucket.MultiBucketsAggregation;
+-import org.opensearch.search.aggregations.metrics.InternalMetricsAggregation;
+-import org.slf4j.Logger;
+-import org.slf4j.LoggerFactory;
+-
+ import java.io.IOException;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+@@ -48,7 +35,6 @@ import java.util.Set;
+ import java.util.TreeSet;
+ import java.util.regex.Matcher;
+ import java.util.regex.Pattern;
+-
+ import com.github.wnameless.json.flattener.JsonFlattener;
+
+ import org.apache.zeppelin.completer.CompletionType;
+@@ -57,12 +43,25 @@ import org.apache.zeppelin.elasticsearch.action.AggWrapper;
+ import org.apache.zeppelin.elasticsearch.action.HitWrapper;
+ import org.apache.zeppelin.elasticsearch.client.ElasticsearchClient;
+ import org.apache.zeppelin.elasticsearch.client.HttpBasedClient;
+-import org.apache.zeppelin.elasticsearch.client.TransportBasedClient;
+ import org.apache.zeppelin.interpreter.Interpreter;
+ import org.apache.zeppelin.interpreter.InterpreterContext;
+ import org.apache.zeppelin.interpreter.InterpreterResult;
+ import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+
++import org.apache.commons.lang3.StringUtils;
++import org.opensearch.common.Strings;
++import org.opensearch.common.xcontent.ToXContent;
++import org.opensearch.common.xcontent.XContentBuilder;
++import org.opensearch.common.xcontent.XContentFactory;
++import org.opensearch.search.aggregations.Aggregation;
++import org.opensearch.search.aggregations.Aggregations;
++import org.opensearch.search.aggregations.InternalMultiBucketAggregation;
++import org.opensearch.search.aggregations.bucket.InternalSingleBucketAggregation;
++import org.opensearch.search.aggregations.bucket.MultiBucketsAggregation;
++import org.opensearch.search.aggregations.metrics.InternalNumericMetricsAggregation;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
+ /**
+ * Elasticsearch Interpreter for Zeppelin.
+ */
+@@ -70,25 +69,25 @@ public class ElasticsearchInterpreter extends Interpreter {
+ private static Logger logger = LoggerFactory.getLogger(ElasticsearchInterpreter.class);
+
+ private static final String HELP = "Elasticsearch interpreter:\n"
+- + "General format: /// \n"
+- + " - indices: list of indices separated by commas (depends on the command)\n"
+- + " - types: list of document types separated by commas (depends on the command)\n"
+- + "Commands:\n"
+- + " - search /indices/types \n"
+- + " . indices and types can be omitted (at least, you have to provide '/')\n"
+- + " . a query is either a JSON-formatted query, nor a lucene query\n"
+- + " - size \n"
+- + " . defines the size of the result set (default value is in the config)\n"
+- + " . if used, this command must be declared before a search command\n"
+- + " - count /indices/types \n"
+- + " . same comments as for the search\n"
+- + " - get /index/type/id\n"
+- + " - delete /index/type/id\n"
+- + " - index /index/type/id \n"
+- + " . the id can be omitted, elasticsearch will generate one";
++ + "General format: /// \n"
++ + " - indices: list of indices separated by commas (depends on the command)\n"
++ + " - types: list of document types separated by commas (depends on the command)\n"
++ + "Commands:\n"
++ + " - search /indices/types \n"
++ + " . indices and types can be omitted (at least, you have to provide '/')\n"
++ + " . a query is either a JSON-formatted query, nor a lucene query\n"
++ + " - size \n"
++ + " . defines the size of the result set (default value is in the config)\n"
++ + " . if used, this command must be declared before a search command\n"
++ + " - count /indices/types \n"
++ + " . same comments as for the search\n"
++ + " - get /index/type/id\n"
++ + " - delete /index/type/id\n"
++ + " - index /index/type/id \n"
++ + " . the id can be omitted, elasticsearch will generate one";
+
+ protected static final List COMMANDS = Arrays.asList(
+- "count", "delete", "get", "help", "index", "search");
++ "count", "delete", "get", "help", "index", "search");
+
+ private static final Pattern FIELD_NAME_PATTERN = Pattern.compile("\\[\\\\\"(.+)\\\\\"\\](.*)");
+
+@@ -119,20 +118,14 @@ public class ElasticsearchInterpreter extends Interpreter {
+ this.resultSize = Integer.parseInt(getProperty(ELASTICSEARCH_RESULT_SIZE));
+ } catch (final NumberFormatException e) {
+ this.resultSize = 10;
+- logger.error("Unable to parse " + ELASTICSEARCH_RESULT_SIZE + " : " +
+- getProperty(ELASTICSEARCH_RESULT_SIZE), e);
++ logger.error("Unable to parse " + ELASTICSEARCH_RESULT_SIZE + " : "
++ + getProperty(ELASTICSEARCH_RESULT_SIZE), e);
+ }
+
+- try {
+- if (StringUtils.isEmpty(clientType) || "transport".equals(clientType)) {
+- elsClient = new TransportBasedClient(getProperties());
+- } else if ("http".equals(clientType)) {
+- elsClient = new HttpBasedClient(getProperties());
+- } else {
+- logger.error("Unknown type of Elasticsearch client: " + clientType);
+- }
+- } catch (final IOException e) {
+- logger.error("Open connection with Elasticsearch", e);
++ if (StringUtils.isEmpty(clientType) || "http".equals(clientType)) {
++ elsClient = new HttpBasedClient(getProperties());
++ } else {
++ logger.error("Unknown type of Elasticsearch client: " + clientType);
+ }
+ }
+
+@@ -155,7 +148,8 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ if (elsClient == null) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Problem with the Elasticsearch client, please check your configuration (host, port,...)");
++ "Problem with the Elasticsearch client, please check your configuration "
++ + "(host, port,...)");
+ }
+
+ String[] items = StringUtils.split(cmd.trim(), " ", 3);
+@@ -172,7 +166,7 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ if (lines.length < 2) {
+ return processHelp(InterpreterResult.Code.ERROR,
+- "Size cmd must be followed by a search");
++ "Size cmd must be followed by a search");
+ }
+
+ final String[] sizeLine = StringUtils.split(lines[0], " ", 2);
+@@ -230,7 +224,7 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ @Override
+ public List completion(String s, int i,
+- InterpreterContext interpreterContext) {
++ InterpreterContext interpreterContext) {
+ final List suggestions = new ArrayList<>();
+
+ for (final String cmd : COMMANDS) {
+@@ -243,8 +237,8 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ private void addAngularObject(InterpreterContext interpreterContext, String prefix, Object obj) {
+ interpreterContext.getAngularObjectRegistry().add(
+- prefix + "_" + interpreterContext.getParagraphId().replace("-", "_"),
+- obj, null, null);
++ prefix + "_" + interpreterContext.getParagraphId().replace("-", "_"),
++ obj, null, null);
+ }
+
+ private String[] getIndexTypeId(String[] urlItems) {
+@@ -257,8 +251,8 @@ public class ElasticsearchInterpreter extends Interpreter {
+ final String id = StringUtils.join(Arrays.copyOfRange(urlItems, 2, urlItems.length), '/');
+
+ if (StringUtils.isEmpty(index)
+- || StringUtils.isEmpty(type)
+- || StringUtils.isEmpty(id)) {
++ || StringUtils.isEmpty(type)
++ || StringUtils.isEmpty(id)) {
+ return null;
+ }
+
+@@ -288,7 +282,7 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ if (indexTypeId == null) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Bad URL (it should be /index/type/id)");
++ "Bad URL (it should be /index/type/id)");
+ }
+
+ final ActionResponse response = elsClient.get(indexTypeId[0], indexTypeId[1], indexTypeId[2]);
+@@ -300,9 +294,9 @@ public class ElasticsearchInterpreter extends Interpreter {
+ addAngularObject(interpreterContext, "get", json);
+
+ return new InterpreterResult(
+- InterpreterResult.Code.SUCCESS,
+- InterpreterResult.Type.TEXT,
+- jsonStr);
++ InterpreterResult.Code.SUCCESS,
++ InterpreterResult.Type.TEXT,
++ jsonStr);
+ }
+
+ return new InterpreterResult(InterpreterResult.Code.ERROR, "Document not found");
+@@ -317,10 +311,10 @@ public class ElasticsearchInterpreter extends Interpreter {
+ * @return Result of the count request, it contains the total hits
+ */
+ private InterpreterResult processCount(String[] urlItems, String data,
+- InterpreterContext interpreterContext) {
++ InterpreterContext interpreterContext) {
+ if (urlItems.length > 2) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Bad URL (it should be /index1,index2,.../type1,type2,...)");
++ "Bad URL (it should be /index1,index2,.../type1,type2,...)");
+ }
+
+ final ActionResponse response = searchData(urlItems, data, 0);
+@@ -328,9 +322,9 @@ public class ElasticsearchInterpreter extends Interpreter {
+ addAngularObject(interpreterContext, "count", response.getTotalHits());
+
+ return new InterpreterResult(
+- InterpreterResult.Code.SUCCESS,
+- InterpreterResult.Type.TEXT,
+- "" + response.getTotalHits());
++ InterpreterResult.Code.SUCCESS,
++ InterpreterResult.Type.TEXT,
++ "" + response.getTotalHits());
+ }
+
+ /**
+@@ -343,17 +337,17 @@ public class ElasticsearchInterpreter extends Interpreter {
+ * @return Result of the search request, it contains a tab-formatted string of the matching hits
+ */
+ private InterpreterResult processSearch(String[] urlItems, String data, int size,
+- InterpreterContext interpreterContext) {
++ InterpreterContext interpreterContext) {
+ if (urlItems.length > 2) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Bad URL (it should be /index1,index2,.../type1,type2,...)");
++ "Bad URL (it should be /index1,index2,.../type1,type2,...)");
+ }
+
+ final ActionResponse response = searchData(urlItems, data, size);
+
+ addAngularObject(interpreterContext, "search",
+- (response.getAggregations() != null && response.getAggregations().size() > 0) ?
+- response.getAggregations() : response.getHits());
++ (response.getAggregations() != null && response.getAggregations().size() > 0)
++ ? response.getAggregations() : response.getHits());
+
+ return buildResponseMessage(response);
+ }
+@@ -368,16 +362,16 @@ public class ElasticsearchInterpreter extends Interpreter {
+ private InterpreterResult processIndex(String[] urlItems, String data) {
+ if (urlItems.length < 2 || urlItems.length > 3) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Bad URL (it should be /index/type or /index/type/id)");
++ "Bad URL (it should be /index/type or /index/type/id)");
+ }
+
+ final ActionResponse response = elsClient.index(
+- urlItems[0], urlItems[1], urlItems.length == 2 ? null : urlItems[2], data);
++ urlItems[0], urlItems[1], urlItems.length == 2 ? null : urlItems[2], data);
+
+ return new InterpreterResult(
+- InterpreterResult.Code.SUCCESS,
+- InterpreterResult.Type.TEXT,
+- response.getHit().getId());
++ InterpreterResult.Code.SUCCESS,
++ InterpreterResult.Type.TEXT,
++ response.getHit().getId());
+ }
+
+ /**
+@@ -391,17 +385,17 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ if (indexTypeId == null) {
+ return new InterpreterResult(InterpreterResult.Code.ERROR,
+- "Bad URL (it should be /index/type/id)");
++ "Bad URL (it should be /index/type/id)");
+ }
+
+ final ActionResponse response =
+- elsClient.delete(indexTypeId[0], indexTypeId[1], indexTypeId[2]);
++ elsClient.delete(indexTypeId[0], indexTypeId[1], indexTypeId[2]);
+
+ if (response.isSucceeded()) {
+ return new InterpreterResult(
+- InterpreterResult.Code.SUCCESS,
+- InterpreterResult.Type.TEXT,
+- response.getHit().getId());
++ InterpreterResult.Code.SUCCESS,
++ InterpreterResult.Type.TEXT,
++ response.getHit().getId());
+ }
+
+ return new InterpreterResult(InterpreterResult.Code.ERROR, "Document not found");
+@@ -428,20 +422,34 @@ public class ElasticsearchInterpreter extends Interpreter {
+ InterpreterResult.Type resType = InterpreterResult.Type.TEXT;
+ String resMsg = "";
+
+- if (agg instanceof InternalMetricsAggregation) {
+- resMsg = XContentHelper.toString((InternalMetricsAggregation) agg).toString();
++ if (agg instanceof InternalNumericMetricsAggregation) {
++ try {
++ XContentBuilder builder = XContentFactory.jsonBuilder();
++ InternalNumericMetricsAggregation tempAgg = (InternalNumericMetricsAggregation) agg;
++ tempAgg.toXContent(builder, ToXContent.EMPTY_PARAMS);
++ resMsg = Strings.toString(builder);
++ } catch (IOException e) {
++ logger.error("Processing bucket: " + e.getMessage(), e);
++ }
+ } else if (agg instanceof InternalSingleBucketAggregation) {
+- resMsg = XContentHelper.toString((InternalSingleBucketAggregation) agg).toString();
++ try {
++ XContentBuilder builder = XContentFactory.jsonBuilder();
++ InternalSingleBucketAggregation tempAgg = (InternalSingleBucketAggregation) agg;
++ tempAgg.toXContent(builder, ToXContent.EMPTY_PARAMS);
++ resMsg = Strings.toString(builder);
++ } catch (IOException e) {
++ logger.error("Processing bucket: " + e.getMessage(), e);
++ }
+ } else if (agg instanceof InternalMultiBucketAggregation) {
+ final Set headerKeys = new HashSet<>();
+ final List> buckets = new LinkedList<>();
+ final InternalMultiBucketAggregation multiBucketAgg = (InternalMultiBucketAggregation) agg;
+-
+- for (final MultiBucketsAggregation.Bucket bucket : multiBucketAgg.getBuckets()) {
++ final List tempBuckets = multiBucketAgg.getBuckets();
++ for (final MultiBucketsAggregation.Bucket bucket : tempBuckets) {
+ try {
+ final XContentBuilder builder = XContentFactory.jsonBuilder();
+ bucket.toXContent(builder, null);
+- final Map bucketMap = JsonFlattener.flattenAsMap(builder.string());
++ final Map bucketMap = JsonFlattener.flattenAsMap(String.valueOf(builder));
+ headerKeys.addAll(bucketMap.keySet());
+ buckets.add(bucketMap);
+ } catch (final IOException e) {
+@@ -474,7 +482,6 @@ public class ElasticsearchInterpreter extends Interpreter {
+
+ private InterpreterResult buildAggResponseMessage(List aggregations) {
+ final InterpreterResult.Type resType = InterpreterResult.Type.TABLE;
+- String resMsg = "";
+
+ final Set headerKeys = new HashSet<>();
+ final List> buckets = new LinkedList<>();
+@@ -501,7 +508,7 @@ public class ElasticsearchInterpreter extends Interpreter {
+ buffer.deleteCharAt(buffer.length() - 1);
+ }
+
+- resMsg = buffer.toString();
++ String resMsg = buffer.toString();
+
+ return new InterpreterResult(InterpreterResult.Code.SUCCESS, resType, resMsg);
+ }
+@@ -527,7 +534,7 @@ public class ElasticsearchInterpreter extends Interpreter {
+ final Matcher fieldNameMatcher = FIELD_NAME_PATTERN.matcher(fieldName);
+ if (fieldNameMatcher.matches()) {
+ flattenMap.put(fieldNameMatcher.group(1) + fieldNameMatcher.group(2),
+- flattenJsonMap.get(fieldName));
++ flattenJsonMap.get(fieldName));
+ } else {
+ flattenMap.put(fieldName, flattenJsonMap.get(fieldName));
+ }
+@@ -571,8 +578,8 @@ public class ElasticsearchInterpreter extends Interpreter {
+ }
+
+ return new InterpreterResult(
+- InterpreterResult.Code.SUCCESS,
+- InterpreterResult.Type.TABLE,
+- buildSearchHitsResponseMessage(response));
++ InterpreterResult.Code.SUCCESS,
++ InterpreterResult.Type.TABLE,
++ buildSearchHitsResponseMessage(response));
+ }
+ }
+diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java
+index 94528168f..e5c096edc 100644
+--- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java
++++ b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/HttpBasedClient.java
+@@ -51,7 +51,8 @@ import org.apache.zeppelin.elasticsearch.action.HitWrapper;
+ */
+ public class HttpBasedClient implements ElasticsearchClient {
+ private static final String QUERY_STRING_TEMPLATE =
+- "{ \"query\": { \"query_string\": { \"query\": \"_Q_\", \"analyze_wildcard\": \"true\" } } }";
++ "{ \"query\": { \"query_string\": " +
++ "{ \"query\": \"_Q_\", \"analyze_wildcard\": \"true\" } } }";
+
+ private final String host;
+ private final int port;
+@@ -119,7 +120,7 @@ public class HttpBasedClient implements ElasticsearchClient {
+ // There are differences: to avoid problems with some special characters
+ // such as / and # in id, use a "terms" query
+ buffer.append("/_search?source=").append(URLEncoder
+- .encode("{\"query\":{\"terms\":{\"_id\":[\"" + id + "\"]}}}", "UTF-8"));
++ .encode("{\"query\":{\"terms\":{\"_id\":[\"" + id + "\"]}}}", "UTF-8"));
+ }
+ } else {
+ buffer.append("/").append(id);
+@@ -155,27 +156,27 @@ public class HttpBasedClient implements ElasticsearchClient {
+ final JsonNode body = new JsonNode(result.getBody());
+ if (body.getObject().has("_index")) {
+ response = new ActionResponse()
+- .succeeded(true)
+- .hit(new HitWrapper(
+- getFieldAsString(body, "_index"),
+- getFieldAsString(body, "_type"),
+- getFieldAsString(body, "_id"),
+- getFieldAsString(body, "_source")));
++ .succeeded(true)
++ .hit(new HitWrapper(
++ getFieldAsString(body, "_index"),
++ getFieldAsString(body, "_type"),
++ getFieldAsString(body, "_id"),
++ getFieldAsString(body, "_source")));
+ } else {
+ final JSONArray hits = getFieldAsArray(body.getObject(), "hits/hits");
+ final JSONObject hit = (JSONObject) hits.iterator().next();
+ response = new ActionResponse()
+- .succeeded(true)
+- .hit(new HitWrapper(
+- hit.getString("_index"),
+- hit.getString("_type"),
+- hit.getString("_id"),
+- hit.opt("_source").toString()));
++ .succeeded(true)
++ .hit(new HitWrapper(
++ hit.getString("_index"),
++ hit.getString("_type"),
++ hit.getString("_id"),
++ hit.opt("_source").toString()));
+ }
+ } else {
+ if (result.getStatus() == 404) {
+ response = new ActionResponse()
+- .succeeded(false);
++ .succeeded(false);
+ } else {
+ throw new ActionException(result.getBody());
+ }
+@@ -201,12 +202,12 @@ public class HttpBasedClient implements ElasticsearchClient {
+ if (isSucceeded) {
+ final JsonNode body = new JsonNode(result.getBody());
+ response = new ActionResponse()
+- .succeeded(true)
+- .hit(new HitWrapper(
+- getFieldAsString(body, "_index"),
+- getFieldAsString(body, "_type"),
+- getFieldAsString(body, "_id"),
+- null));
++ .succeeded(true)
++ .hit(new HitWrapper(
++ getFieldAsString(body, "_index"),
++ getFieldAsString(body, "_type"),
++ getFieldAsString(body, "_id"),
++ null));
+ } else {
+ throw new ActionException(result.getBody());
+ }
+@@ -227,9 +228,9 @@ public class HttpBasedClient implements ElasticsearchClient {
+ request = Unirest.put(getUrl(index, type, id, false));
+ }
+ request
+- .header("Accept", "application/json")
+- .header("Content-Type", "application/json")
+- .body(data).getHttpRequest();
++ .header("Accept", "application/json")
++ .header("Content-Type", "application/json")
++ .body(data).getHttpRequest();
+ if (StringUtils.isNotEmpty(username)) {
+ request.basicAuth(username, password);
+ }
+@@ -239,12 +240,12 @@ public class HttpBasedClient implements ElasticsearchClient {
+
+ if (isSucceeded) {
+ response = new ActionResponse()
+- .succeeded(true)
+- .hit(new HitWrapper(
+- getFieldAsString(result, "_index"),
+- getFieldAsString(result, "_type"),
+- getFieldAsString(result, "_id"),
+- null));
++ .succeeded(true)
++ .hit(new HitWrapper(
++ getFieldAsString(result, "_index"),
++ getFieldAsString(result, "_type"),
++ getFieldAsString(result, "_id"),
++ null));
+ } else {
+ throw new ActionException(result.getBody().toString());
+ }
+@@ -271,8 +272,8 @@ public class HttpBasedClient implements ElasticsearchClient {
+
+ try {
+ final HttpRequestWithBody request = Unirest
+- .post(getUrl(indices, types) + "/_search?size=" + size)
+- .header("Content-Type", "application/json");
++ .post(getUrl(indices, types) + "/_search?size=" + size)
++ .header("Content-Type", "application/json");
+
+ if (StringUtils.isNoneEmpty(query)) {
+ request.header("Accept", "application/json").body(query);
+@@ -289,8 +290,8 @@ public class HttpBasedClient implements ElasticsearchClient {
+ final long total = getFieldAsLong(result, "hits/total");
+
+ response = new ActionResponse()
+- .succeeded(true)
+- .totalHits(total);
++ .succeeded(true)
++ .totalHits(total);
+
+ if (containsAggs(result)) {
+ JSONObject aggregationsMap = body.getJSONObject("aggregations");
+@@ -305,11 +306,11 @@ public class HttpBasedClient implements ElasticsearchClient {
+ final Iterator buckets = aggResult.getJSONArray("buckets").iterator();
+ while (buckets.hasNext()) {
+ response.addAggregation(
+- new AggWrapper(AggregationType.MULTI_BUCKETS, buckets.next().toString()));
++ new AggWrapper(AggregationType.MULTI_BUCKETS, buckets.next().toString()));
+ }
+ } else {
+ response.addAggregation(
+- new AggWrapper(AggregationType.SIMPLE, aggregationsMap.toString()));
++ new AggWrapper(AggregationType.SIMPLE, aggregationsMap.toString()));
+ }
+ break; // Keep only one aggregation
+ }
+@@ -320,12 +321,12 @@ public class HttpBasedClient implements ElasticsearchClient {
+ while (iter.hasNext()) {
+ final JSONObject hit = (JSONObject) iter.next();
+ final Object data =
+- hit.opt("_source") != null ? hit.opt("_source") : hit.opt("fields");
++ hit.opt("_source") != null ? hit.opt("_source") : hit.opt("fields");
+ response.addHit(new HitWrapper(
+- hit.getString("_index"),
+- hit.getString("_type"),
+- hit.getString("_id"),
+- data.toString()));
++ hit.getString("_index"),
++ hit.getString("_type"),
++ hit.getString("_id"),
++ data.toString()));
+ }
+ }
+ } else {
+@@ -340,8 +341,8 @@ public class HttpBasedClient implements ElasticsearchClient {
+
+ private boolean containsAggs(HttpResponse result) {
+ return result.getBody() != null &&
+- (result.getBody().getObject().has("aggregations") ||
+- result.getBody().getObject().has("aggs"));
++ (result.getBody().getObject().has("aggregations") ||
++ result.getBody().getObject().has("aggs"));
+ }
+
+ @Override
+diff --git a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/TransportBasedClient.java b/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/TransportBasedClient.java
+deleted file mode 100644
+index 2af37bd3c..000000000
+--- a/elasticsearch/src/main/java/org/apache/zeppelin/elasticsearch/client/TransportBasedClient.java
++++ /dev/null
+@@ -1,230 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one or more
+- * contributor license agreements. See the NOTICE file distributed with
+- * this work for additional information regarding copyright ownership.
+- * The ASF licenses this file to You under the Apache License, Version 2.0
+- * (the "License"); you may not use this file except in compliance with
+- * the License. You may obtain a copy of the License at
+- *
+- * http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing, software
+- * distributed under the License is distributed on an "AS IS" BASIS,
+- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+- * See the License for the specific language governing permissions and
+- * limitations under the License.
+- */
+-
+-package org.apache.zeppelin.elasticsearch.client;
+-
+-import com.google.gson.Gson;
+-import com.google.gson.GsonBuilder;
+-import com.google.gson.JsonSyntaxException;
+-
+-import org.apache.commons.lang3.StringUtils;
+-import org.opensearch.action.delete.DeleteResponse;
+-import org.opensearch.action.get.GetResponse;
+-import org.opensearch.action.index.IndexResponse;
+-import org.opensearch.action.search.SearchAction;
+-import org.opensearch.action.search.SearchRequestBuilder;
+-import org.opensearch.action.search.SearchResponse;
+-import org.opensearch.client.Client;
+-import org.opensearch.client.transport.TransportClient;
+-import org.opensearch.common.settings.Settings;
+-import org.opensearch.common.transport.InetSocketTransportAddress;
+-import org.opensearch.common.xcontent.XContentBuilder;
+-import org.opensearch.common.xcontent.XContentFactory;
+-import org.opensearch.common.xcontent.XContentHelper;
+-import org.opensearch.index.query.QueryBuilders;
+-import org.opensearch.search.SearchHit;
+-import org.opensearch.search.SearchHitField;
+-import org.opensearch.search.aggregations.Aggregation;
+-import org.opensearch.search.aggregations.Aggregations;
+-import org.opensearch.search.aggregations.InternalMultiBucketAggregation;
+-import org.opensearch.search.aggregations.bucket.InternalSingleBucketAggregation;
+-import org.opensearch.search.aggregations.bucket.MultiBucketsAggregation;
+-import org.opensearch.search.aggregations.metrics.InternalMetricsAggregation;
+-
+-import java.io.IOException;
+-import java.net.InetAddress;
+-import java.net.UnknownHostException;
+-import java.util.HashMap;
+-import java.util.HashSet;
+-import java.util.LinkedList;
+-import java.util.List;
+-import java.util.Map;
+-import java.util.Properties;
+-import java.util.Set;
+-
+-import org.apache.zeppelin.elasticsearch.ElasticsearchInterpreter;
+-import org.apache.zeppelin.elasticsearch.action.ActionResponse;
+-import org.apache.zeppelin.elasticsearch.action.AggWrapper;
+-import org.apache.zeppelin.elasticsearch.action.HitWrapper;
+-
+-/**
+- * Elasticsearch client using the transport protocol.
+- */
+-public class TransportBasedClient implements ElasticsearchClient {
+- private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+- private final Client client;
+-
+- public TransportBasedClient(Properties props) throws UnknownHostException {
+- final String host =
+- props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_HOST);
+- final int port = Integer.parseInt(
+- props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_PORT));
+- final String clusterName =
+- props.getProperty(ElasticsearchInterpreter.ELASTICSEARCH_CLUSTER_NAME);
+-
+- final Settings settings = Settings.settingsBuilder()
+- .put("cluster.name", clusterName)
+- .put(props)
+- .build();
+-
+- client = TransportClient.builder().settings(settings).build()
+- .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port));
+- }
+-
+- @Override
+- public ActionResponse get(String index, String type, String id) {
+- final GetResponse getResp = client
+- .prepareGet(index, type, id)
+- .get();
+-
+- return new ActionResponse()
+- .succeeded(getResp.isExists())
+- .hit(new HitWrapper(
+- getResp.getIndex(),
+- getResp.getType(),
+- getResp.getId(),
+- getResp.getSourceAsString()));
+- }
+-
+- @Override
+- public ActionResponse delete(String index, String type, String id) {
+- final DeleteResponse delResp = client
+- .prepareDelete(index, type, id)
+- .get();
+-
+- return new ActionResponse()
+- .succeeded(delResp.isFound())
+- .hit(new HitWrapper(
+- delResp.getIndex(),
+- delResp.getType(),
+- delResp.getId(),
+- null));
+- }
+-
+- @Override
+- public ActionResponse index(String index, String type, String id, String data) {
+- final IndexResponse idxResp = client
+- .prepareIndex(index, type, id)
+- .setSource(data)
+- .get();
+-
+- return new ActionResponse()
+- .succeeded(idxResp.isCreated())
+- .hit(new HitWrapper(
+- idxResp.getIndex(),
+- idxResp.getType(),
+- idxResp.getId(),
+- null));
+- }
+-
+- @Override
+- public ActionResponse search(String[] indices, String[] types, String query, int size) {
+- final SearchRequestBuilder reqBuilder = new SearchRequestBuilder(
+- client, SearchAction.INSTANCE);
+- reqBuilder.setIndices();
+-
+- if (indices != null) {
+- reqBuilder.setIndices(indices);
+- }
+- if (types != null) {
+- reqBuilder.setTypes(types);
+- }
+-
+- if (!StringUtils.isEmpty(query)) {
+- // The query can be either JSON-formatted, nor a Lucene query
+- // So, try to parse as a JSON => if there is an error, consider the query a Lucene one
+- try {
+- @SuppressWarnings("rawtypes")
+- final Map source = gson.fromJson(query, Map.class);
+- reqBuilder.setExtraSource(source);
+- } catch (final JsonSyntaxException e) {
+- // This is not a JSON (or maybe not well formatted...)
+- reqBuilder.setQuery(QueryBuilders.queryStringQuery(query).analyzeWildcard(true));
+- }
+- }
+-
+- reqBuilder.setSize(size);
+-
+- final SearchResponse searchResp = reqBuilder.get();
+-
+- final ActionResponse actionResp = new ActionResponse()
+- .succeeded(true)
+- .totalHits(searchResp.getHits().getTotalHits());
+-
+- if (searchResp.getAggregations() != null) {
+- setAggregations(searchResp.getAggregations(), actionResp);
+- } else {
+- for (final SearchHit hit: searchResp.getHits()) {
+- // Fields can be found either in _source, or in fields (it depends on the query)
+- // => specific for elasticsearch's version < 5
+- //
+- String src = hit.getSourceAsString();
+- if (src == null) {
+- final Map hitFields = new HashMap<>();
+- for (final SearchHitField hitField : hit.getFields().values()) {
+- hitFields.put(hitField.getName(), hitField.getValues());
+- }
+- src = gson.toJson(hitFields);
+- }
+- actionResp.addHit(new HitWrapper(hit.getIndex(), hit.getType(), hit.getId(), src));
+- }
+- }
+-
+- return actionResp;
+- }
+-
+- private void setAggregations(Aggregations aggregations, ActionResponse actionResp) {
+- // Only the result of the first aggregation is returned
+- //
+- final Aggregation agg = aggregations.asList().get(0);
+-
+- if (agg instanceof InternalMetricsAggregation) {
+- actionResp.addAggregation(new AggWrapper(AggWrapper.AggregationType.SIMPLE,
+- XContentHelper.toString((InternalMetricsAggregation) agg).toString()));
+- } else if (agg instanceof InternalSingleBucketAggregation) {
+- actionResp.addAggregation(new AggWrapper(AggWrapper.AggregationType.SIMPLE,
+- XContentHelper.toString((InternalSingleBucketAggregation) agg).toString()));
+- } else if (agg instanceof InternalMultiBucketAggregation) {
+- final Set headerKeys = new HashSet<>();
+- final List> buckets = new LinkedList<>();
+- final InternalMultiBucketAggregation multiBucketAgg = (InternalMultiBucketAggregation) agg;
+-
+- for (final MultiBucketsAggregation.Bucket bucket : multiBucketAgg.getBuckets()) {
+- try {
+- final XContentBuilder builder = XContentFactory.jsonBuilder();
+- bucket.toXContent(builder, null);
+- actionResp.addAggregation(
+- new AggWrapper(AggWrapper.AggregationType.MULTI_BUCKETS, builder.string()));
+- } catch (final IOException e) {
+- // Ignored
+- }
+- }
+- }
+- }
+-
+- @Override
+- public void close() {
+- if (client != null) {
+- client.close();
+- }
+- }
+-
+- @Override
+- public String toString() {
+- return "TransportBasedClient []";
+- }
+-}
+diff --git a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java
+index a806dc314..4cf42569a 100644
+--- a/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java
++++ b/elasticsearch/src/test/java/org/apache/zeppelin/elasticsearch/ElasticsearchInterpreterTest.java
+@@ -23,10 +23,12 @@ import static org.junit.Assert.assertNotNull;
+
+ import org.apache.commons.lang3.RandomUtils;
+ import org.opensearch.action.admin.indices.delete.DeleteIndexRequest;
++import org.opensearch.action.support.WriteRequest;
+ import org.opensearch.client.Client;
+ import org.opensearch.common.settings.Settings;
++import org.opensearch.env.Environment;
++import org.opensearch.monitor.fs.FsInfo;
+ import org.opensearch.node.Node;
+-import org.opensearch.node.NodeBuilder;
+ import org.junit.AfterClass;
+ import org.junit.Assert;
+ import org.junit.BeforeClass;
+@@ -36,6 +38,7 @@ import org.junit.experimental.theories.Theory;
+ import org.junit.runner.RunWith;
+
+ import java.io.IOException;
++import java.nio.file.Path;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Date;
+@@ -72,7 +75,8 @@ public class ElasticsearchInterpreterTest {
+
+ @BeforeClass
+ public static void populate() throws IOException {
+- final Settings settings = Settings.settingsBuilder()
++
++ final Settings settings = Settings.builder()
+ .put("cluster.name", ELS_CLUSTER_NAME)
+ .put("network.host", ELS_HOST)
+ .put("http.port", ELS_HTTP_PORT)
+@@ -80,7 +84,8 @@ public class ElasticsearchInterpreterTest {
+ .put("path.home", ELS_PATH)
+ .build();
+
+- elsNode = NodeBuilder.nodeBuilder().settings(settings).node();
++ final Environment env = new Environment(settings, (Path) FsInfo.Path.EMPTY_PARAMS);
++ elsNode = new Node(env);
+ elsClient = elsNode.client();
+
+ elsClient.admin().indices().prepareCreate("logs")
+@@ -93,7 +98,7 @@ public class ElasticsearchInterpreterTest {
+
+ for (int i = 0; i < 48; i++) {
+ elsClient.prepareIndex("logs", "http", "" + i)
+- .setRefresh(true)
++ .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+ .setSource(jsonBuilder()
+ .startObject()
+ .field("date", new Date())
+@@ -110,7 +115,7 @@ public class ElasticsearchInterpreterTest {
+
+ for (int i = 1; i < 3; i++) {
+ elsClient.prepareIndex("logs", "http", "very/strange/id#" + i)
+- .setRefresh(true)
++ .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
+ .setSource(jsonBuilder()
+ .startObject()
+ .field("date", new Date())
+@@ -141,7 +146,7 @@ public class ElasticsearchInterpreterTest {
+ }
+
+ @AfterClass
+- public static void clean() {
++ public static void clean() throws IOException {
+ if (transportInterpreter != null) {
+ transportInterpreter.close();
+ }
+diff --git a/pom.xml b/pom.xml
+index 7f4ec216b..cef5f418d 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -19,1824 +19,144 @@
+
+
+- 4.0.0
++ 4.0.0
++
++
++ zeppelin
++ org.apache.zeppelin
++ 0.9.0-preview2
++ ..
++
++
++ org.apache.zeppelin
++ zengine-plugins-parent
++ pom
++ 0.9.0-preview2
++ Zeppelin: Plugins Parent
++ Zeppelin Plugins Parent
++
++
++ provided
++
++
++
++ notebookrepo/s3
++ notebookrepo/github
++ notebookrepo/azure
++ notebookrepo/gcs
++ notebookrepo/zeppelin-hub
++ notebookrepo/filesystem
++ notebookrepo/mongo
++ notebookrepo/oss
++
++ launcher/k8s-standard
++ launcher/cluster
++ launcher/docker
++ launcher/yarn
++ launcher/flink
++
+
+- org.apache.zeppelin
+- zeppelin
+- pom
+- 0.9.0-preview2
+- Zeppelin
+- Zeppelin project
+- https://zeppelin.apache.org
+-
+-
+- org.apache
+- apache
+- 17
+-
+-
+-
+-
+- The Apache Software License, Version 2.0
+- https://www.apache.org/licenses/LICENSE-2.0.txt
+- repo
+-
+-
+-
+-
+- https://git-wip-us.apache.org/repos/asf/zeppelin.git
+- scm:git:https://git-wip-us.apache.org/repos/asf/zeppelin.git
+- scm:git:https://git-wip-us.apache.org/repos/asf/zeppelin.git
+-
+-
+- 2013
+-
+-
+- zeppelin-interpreter-parent
+- zeppelin-interpreter
+- zeppelin-interpreter-shaded
+- zeppelin-zengine
+- zeppelin-display
+- rlang
+- zeppelin-jupyter-interpreter
+- zeppelin-jupyter-interpreter-shaded
+- kotlin
+- groovy
+- spark
+- submarine
+- markdown
+- mongodb
+- angular
+- shell
+- livy
+- hbase
+- pig
+- jdbc
+- file
+- flink
+- ignite
+- influxdb
+- kylin
+- python
+- lens
+- cassandra
+- elasticsearch
+- bigquery
+- alluxio
+- scio
+- neo4j
+- sap
+- scalding
+- java
+- beam
+- hazelcastjet
+- geode
+- ksql
+- sparql
+- zeppelin-web
+- zeppelin-server
+- zeppelin-jupyter
+- zeppelin-plugins
+- zeppelin-distribution
+-
+-
+-
+-
+- 1.8
+- 2.10.5
+- ${scala.2.10.version}
+- 2.10
+- 2.11.8
+- 3.0.7
+- 1.12.5
+-
+-
+- v12.3.1
+- 6.9.0
+- 1.6
+-
+-
+- 1.7.30
+- 1.2.17
+- 0.13.0
+- 2.2
+- 0.2.1
+- 9.4.27.v20200227
+- 4.4.1
+- 4.5.1
+- 4.0.2
+- 1.20
+- 3.10
+- 1.9
+- 1.3
+- 1.14
+- 2.6
+- 3.2.2
+- 1.1.1
+- 1.4
+- 1.4.2
+- 2.9.9
+- 1.60
+-
+- 2.7.7
+- 2.6.5
+- 3.0.3
+- 3.1.3
+- 3.2.0
+- ${hadoop2.7.version}
+-
+- provided
+- 2.3.2
+- 1.4.0
+- 1.13.1
+-
+-
+- 4.12
+- 1.10.19
+- 1.7.0
+- 1.6.4
+-
+-
+- 1.8
+- 3.2.0
+- 1.7.7
+- 1.7
+- 1.4
+- 2.17
+- 3.1.0
+- 2.7
+- 3.8.1
+- 3.1.2
+- 2.8.2
+- 1.3.0
+- 2.8
+- 3.0.0-M3
+- 1.6.0
+- 2.17
+- 4.0.0
+- 1.6
+- 3.0.0-M1
+- 3.2.0
+- 3.2.0
+- 1.8
+- 1.0.0
+- 0.5.0
+- 0.13
+- 1.7.0
+- 3.1.0
+- 1.4
+- 3.4.6
+- 2.15.2
+- 1.7.1
+- 2.0.0
+- 1.11.2
+- 3.2.2
+- 3.2.1
+- 2.17
+- 1.0.2
+-
+- false
+-
+- 512m
+-
+-
+-
+-
+-
+-
+
+-
+-
+- org.slf4j
+- slf4j-api
+- ${slf4j.version}
+-
+-
+-
+- org.slf4j
+- slf4j-log4j12
+- ${slf4j.version}
+-
+-
+-
+- log4j
+- log4j
+- ${log4j.version}
+-
+-
+-
+- org.apache.thrift
+- libthrift
+- ${libthrift.version}
+-
+-
+- javax.annotation
+- javax.annotation-api
+-
+-
+-
+-
+-
+- org.apache.httpcomponents
+- httpcore
+- ${httpcomponents.core.version}
+-
+-
+-
+- org.apache.httpcomponents
+- httpclient
+- ${httpcomponents.client.version}
+-
+-
+-
+- org.apache.httpcomponents
+- httpasyncclient
+- ${httpcomponents.asyncclient.version}
+-
+-
+-
+- org.apache.commons
+- commons-lang3
+- ${commons.lang3.version}
+-
+-
+-
+- org.apache.commons
+- commons-exec
+- ${commons.exec.version}
+-
+-
+-
+- com.google.code.gson
+- gson
+- ${gson.version}
+-
+-
+-
+- org.danilopianini
+- gson-extras
+- ${gson-extras.version}
+-
+-
+-
+- commons-configuration
+- commons-configuration
+- ${commons.configuration.version}
+-
+-
+-
+- commons-codec
+- commons-codec
+- ${commons.codec.version}
+-
+-
+-
+- commons-io
+- commons-io
+- ${commons.io.version}
+-
+-
+-
+- commons-collections
+- commons-collections
+- ${commons.collections.version}
+-
+-
+-
+- commons-logging
+- commons-logging
+- ${commons.logging.version}
+-
+-
+-
+- commons-cli
+- commons-cli
+- ${commons.cli.version}
+-
+-
+-
+- joda-time
+- joda-time
+- ${joda.version}
+-
+-
+-
+-
+- org.apache.shiro
+- shiro-core
+- ${shiro.version}
+-
+-
+- org.apache.shiro
+- shiro-web
+- ${shiro.version}
+-
+-
+- org.apache.shiro
+- shiro-config-core
+- ${shiro.version}
+-
+-
+-
+- org.bouncycastle
+- bcpkix-jdk15on
+- ${bouncycastle.version}
+-
+-
+-
+- com.amazonaws
+- aws-java-sdk-s3
+- ${aws.sdk.s3.version}
+-
+-
+-
+- org.codehaus.jettison
+- jettison
+- ${jettison.version}
+-
+-
+-
+- org.apache.hadoop
+- hadoop-client
+- ${hadoop.version}
+- ${hadoop.deps.scope}
+-
+-
+- com.sun.jersey
+- jersey-core
+-
+-
+- com.sun.jersey
+- jersey-json
+-
+-
+- com.sun.jersey
+- jersey-client
+-
+-
+- com.sun.jersey
+- jersey-server
+-
+-
+- javax.servlet
+- servlet-api
+-
+-
+- org.apache.avro
+- avro
+-
+-
+- org.apache.jackrabbit
+- jackrabbit-webdav
+-
+-
+- io.netty
+- netty
+-
+-
+- io.netty
+- netty-all
+-
+-
+- commons-httpclient
+- commons-httpclient
+-
+-
+- org.eclipse.jgit
+- org.eclipse.jgit
+-
+-
+- com.jcraft
+- jsch
+-
+-
+- org.apache.commons
+- commons-compress
+-
+-
+- xml-apis
+- xml-apis
+-
+-
+- xerces
+- xercesImpl
+-
+-
+- com.google.guava
+- guava
+-
+-
+- com.google.code.findbugs
+- jsr305
+-
+-
+- org.apache.commons
+- commons-math3
+-
+-
+- com.fasterxml.jackson.core
+- jackson-annotations
+-
+-
+- com.nimbusds
+- nimbus-jose-jwt
+-
+-
+- org.eclipse.jetty
+- jetty-xml
+-
+-
+- org.eclipse.jetty
+- jetty-servlet
+-
+-
+- org.eclipse.jetty
+- jetty-util
+-
+-
+- commons-beanutils
+- commons-beanutils
+-
+-
+- org.apache.commons
+- commons-configuration2
+-
+-
+- org.eclipse.jetty
+- jetty-webapp
+-
+-
+- com.fasterxml.jackson.module
+- jackson-module-jaxb-annotations
+-
+-
+- com.fasterxml.jackson.core
+- jackson-core
+-
+-
+- com.fasterxml.jackson.core
+- jackson-databind
+-
+-
+-
+-
+-
+- org.apache.hadoop
+- hadoop-yarn-api
+- ${hadoop.version}
+- ${hadoop.deps.scope}
+-
+-
+- javax.servlet
+- servlet-api
+-
+-
+- org.apache.avro
+- avro
+-
+-
+- org.apache.jackrabbit
+- jackrabbit-webdav
+-
+-
+- io.netty
+- netty
+-
+-
+- commons-httpclient
+- commons-httpclient
+-
+-
+- org.eclipse.jgit
+- org.eclipse.jgit
+-
+-
+- com.jcraft
+- jsch
+-
+-
+- org.apache.commons
+- commons-compress
+-
+-
+- xml-apis
+- xml-apis
+-
+-
+- xerces
+- xercesImpl
+-
+-
+- org.codehaus.jackson
+- jackson-mapper-asl
+-
+-
+- org.codehaus.jackson
+- jackson-core-asl
+-
+-
+- com.google.guava
+- guava
+-
+-
+- com.google.code.findbugs
+- jsr305
+-
+-
+- org.apache.commons
+- commons-math3
+-
+-
+-
+-
+-
+- org.apache.hadoop
+- hadoop-hdfs
+- ${hadoop.version}
+- tests
+- test
+-
+-
+- com.sun.jersey
+- jersey-json
+-
+-
+- com.sun.jersey
+- jersey-client
+-
+-
+- javax.servlet
+- servlet-api
+-
+-
+- org.apache.avro
+- avro
+-
+-
+- org.apache.jackrabbit
+- jackrabbit-webdav
+-
+-
+- io.netty
+- netty
+-
+-
+- commons-httpclient
+- commons-httpclient
+-
+-
+- org.eclipse.jgit
+- org.eclipse.jgit
+-
+-
+- com.jcraft
+- jsch
+-
+-
+- org.apache.commons
+- commons-compress
+-
+-
+- xml-apis
+- xml-apis
+-
+-
+- xerces
+- xercesImpl
+-
+-
+- com.google.guava
+- guava
+-
+-
+- io.netty
+- netty-all
+-
+-
+- org.eclipse.jetty
+- jetty-util
+-
+-
+- com.fasterxml.jackson.core
+- jackson-annotations
+-
+-
+-
+-
+-
+- org.apache.hadoop
+- hadoop-common
+- ${hadoop.version}
+- tests
+- test
+-
+-
+- com.sun.jersey
+- jersey-core
+-
+-
+- com.sun.jersey
+- jersey-json
+-
+-
+- com.sun.jersey
+- jersey-client
+-
+-
+- com.sun.jersey
+- jersey-server
+-
+-
+- javax.servlet
+- servlet-api
+-
+-
+- org.apache.avro
+- avro
+-
+-
+- org.apache.jackrabbit
+- jackrabbit-webdav
+-
+-
+- io.netty
+- netty
+-
+-
+- commons-httpclient
+- commons-httpclient
+-
+-
+- org.eclipse.jgit
+- org.eclipse.jgit
+-
+-
+- com.jcraft
+- jsch
+-
+-
+- org.apache.commons
+- commons-compress
+-
+-
+- xml-apis
+- xml-apis
+-
+-
+- xerces
+- xercesImpl
+-
+-
+- org.codehaus.jackson
+- jackson-mapper-asl
+-
+-
+- org.codehaus.jackson
+- jackson-core-asl
+-
+-
+- com.google.guava
+- guava
+-
+-
+- com.google.code.findbugs
+- jsr305
+-
+-
+- org.apache.commons
+- commons-math3
+-
+-
+- commons-beanutils
+- commons-beanutils
+-
+-
+- org.apache.commons
+- commons-configuration2
+-
+-
+- org.apache.zookeeper
+- zookeeper
+-
+-
+- org.eclipse.jetty
+- jetty-servlet
+-
+-
+- org.eclipse.jetty
+- jetty-util
+-
+-
+- org.eclipse.jetty
+- jetty-webapp
+-
+-
+- org.eclipse.jetty
+- jetty-server
+-
+-
+- com.nimbusds
+- nimbus-jose-jwt
+-
+-
+- com.fasterxml.jackson.core
+- jackson-databind
+-
+-
+-
+-
+-
+- org.apache.hadoop
+- hadoop-yarn-server-tests
+- ${hadoop.version}
+- tests
+- test
+-
+-
+- com.sun.jersey
+- jersey-core
+-
+-
+- com.sun.jersey
+- jersey-client
+-
+-
+- com.sun.jersey
+- jersey-server
+-
+-
+- javax.servlet
+- servlet-api
+-
+-
+- org.apache.avro
+- avro
+-
+-
+- org.apache.jackrabbit
+- jackrabbit-webdav
+-
+-
+- io.netty
+- netty
+-
+-
+- commons-httpclient
+- commons-httpclient
+-
+-
+- org.eclipse.jgit
+- org.eclipse.jgit
+-
+-
+- com.jcraft
+- jsch
+-
+-
+- org.apache.commons
+- commons-compress
+-
+-
+- xml-apis
+- xml-apis
+-
+-
+- xerces
+- xercesImpl
+-
+-
+- org.codehaus.jackson
+- jackson-core-asl
+-
+-
+- org.codehaus.jackson
+- jackson-jaxrs
+-
+-
+- org.codehaus.jackson
+- jackson-xc
+-
+-
+- org.codehaus.jackson
+- jackson-mapper-asl
+-
+-
+- com.google.guava
+- guava
+-
+-
+- javax.xml.bind
+- jaxb-api
+-
+-
+- com.fasterxml.jackson.core
+- jackson-core
+-
+-
+- org.eclipse.jetty
+- jetty-util
+-
+-
+- com.zaxxer
+- HikariCP-java7
+-
+-
+- com.google.inject
+- guice
+-
+-
+- com.fasterxml.jackson.core
+- jackson-annotations
+-
+-
+- com.fasterxml.jackson.module
+- jackson-module-jaxb-annotations
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- junit
+- junit
+- ${junit.version}
+- test
+-
+-
+-
+- org.assertj
+- assertj-core
+- ${assertj.version}
+- test
+-
+-
+-
+- org.mockito
+- mockito-core
+- ${mockito.version}
+- test
+-
+-
+-
+- org.mockito
+- mockito-all
+- ${mockito.version}
+- test
+-
+-
+-
+- org.powermock
+- powermock-api-mockito
+- ${powermock.version}
+- test
+-
+-
+-
+- org.powermock
+- powermock-core
+- ${powermock.version}
+- test
+-
+-
+-
+- org.powermock
+- powermock-module-junit4
+- ${powermock.version}
+- test
+-
+-
+-
+- org.powermock
+- powermock-reflect
+- ${powermock.version}
+- test
+-
++
++ ${project.groupId}
++ zeppelin-zengine
++ ${project.version}
++ provided
++
++
++ com.fasterxml.jackson.core
++ jackson-core
++
++
++
++
++
++ ${project.groupId}
++ zeppelin-zengine
++ ${project.version}
++ tests
++ test
++
++
++
++
++ junit
++ junit
++ test
++
++
++
++ org.mockito
++ mockito-all
++ test
++
+
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-compiler-plugin
+- ${plugin.compiler.version}
+-
+- ${java.version}
+- ${java.version}
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-checkstyle-plugin
+- ${plugin.checkstyle.version}
+-
+- true
+- false
+- true
+- ${basedir}/src/main/java,${basedir}/src/main/scala
+- ${basedir}/src/test/java
+- _tools/checkstyle.xml
+- ${basedir}/target/checkstyle-output.xml
+- ${project.build.sourceEncoding}
+- ${project.reporting.outputEncoding}
+-
+-
+-
+- checkstyle-fail-build
+- validate
+-
+- check
+-
+-
+- true
+- org/apache/zeppelin/interpreter/thrift/*,org/apache/zeppelin/scio/avro/*,org/apache/zeppelin/python/proto/*
+-
+-
+-
+- checkstyle-gen-html-report
+- install
+-
+- checkstyle-aggregate
+-
+-
+- org/apache/zeppelin/interpreter/thrift/*,org/apache/zeppelin/scio/avro/*,org/apache/zeppelin/python/proto/*
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-jar-plugin
+- ${plugin.jar.version}
+-
+-
+-
+- true
+- lib/
+- theMainClass
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-remote-resources-plugin
+- ${plugin.remote.resource.version}
+-
+-
+- process-remote-resources
+-
+- process
+-
+-
+-
+- org.apache:apache-jar-resource-bundle:1.0
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-scm-plugin
+- ${plugin.scm.version}
+-
+- developerConnection
+- branch-0.1
+- branch
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-enforcer-plugin
+- ${plugin.enforcer.version}
+-
+-
+- enforce
+-
+-
+-
+-
+- true
+-
+-
+- enforce
+-
+-
+-
+-
+- enforce-maven
+-
+- enforce
+-
+-
+-
+-
+- [3.1.0,)
+-
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-deploy-plugin
+- ${plugin.deploy.version}
+-
+-
+-
+- pl.project13.maven
+- git-commit-id-plugin
+- ${plugin.git.commit.id.version}
+-
+-
+-
+- revision
+-
+-
+-
+-
+- false
+- ${project.basedir}/.git
+- ${plugin.gitcommitid.useNativeGit}
+- true
+- ${project.build.outputDirectory}/git.properties
+- false
+- yyyy-MM-dd HH:mm:ss
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-shade-plugin
+- ${plugin.shade.version}
+-
+
+-
+- org.apache.maven.plugins
+- maven-install-plugin
+- ${plugin.install.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-checkstyle-plugin
+- ${plugin.checkstyle.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-clean-plugin
+- ${plugin.clean.version}
+-
+-
+-
+- net.alchim31.maven
+- scala-maven-plugin
+- ${plugin.scala.alchim31.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-surefire-plugin
+- ${plugin.surefire.version}
+-
+- -Xmx2g -Xms1g -Dfile.encoding=UTF-8
+-
+- true
+-
+-
+- ${tests.to.exclude}
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-assembly-plugin
+- ${plugin.assembly.version}
+-
+-
+-
+- org.codehaus.mojo
+- exec-maven-plugin
+- ${plugin.exec.version}
+-
+-
+-
+- org.codehaus.mojo
+- cobertura-maven-plugin
+- ${plugin.cobertura.version}
+-
+-
+-
+- org.codehaus.mojo
+- xml-maven-plugin
+- ${plugin.xml.version}
+-
+-
+- verify
+-
+- validate
+-
+-
+-
+-
+-
+-
+- ${project.basedir}
+-
+-
+- pom.xml
+-
+-
+- _tools/maven-4.0.0.xsd
+-
+-
+-
+-
+-
+-
+- com.googlecode.maven-download-plugin
+- download-maven-plugin
+- ${plugin.download.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-antrun-plugin
+- ${plugin.antrun.version}
+-
+-
+-
+-
+- org.eclipse.m2e
+- lifecycle-mapping
+- ${plugin.lifecycle.mapping.version}
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+-
+-
+- maven-dependency-plugin
+-
+-
+- [2.8,)
+-
+-
+- copy-dependencies
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+-
+-
+- maven-checkstyle-plugin
+-
+-
+- [2.13,)
+-
+-
+- checkstyle
+- check
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-eclipse-plugin
+- ${plugin.eclipse.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-dependency-plugin
+- ${plugin.dependency.version}
+-
+-
+- copy-dependencies
+- process-test-resources
+-
+- copy-dependencies
+-
+-
+- ${project.build.directory}/lib
+- false
+- false
+- true
+- runtime
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-resources-plugin
+- ${plugin.resource.version}
+-
+-
+- copy-resources
+- validate
+-
+- copy-resources
+-
+-
+- ${basedir}/target/site
+-
+-
+- ${basedir}/../_tools/site
+- true
+-
+- **/*
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- org.scalatest
+- scalatest-maven-plugin
+- ${plugin.scalatest.version}
+-
+-
+-
+- org.codehaus.mojo
+- build-helper-maven-plugin
+- ${plugin.buildhelper.version}
+-
+-
+-
+- com.github.eirslett
+- frontend-maven-plugin
+- ${plugin.frontend.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-failsafe-plugin
+- ${plugin.failsafe.version}
+-
+-
+-
+- org.xolstice.maven.plugins
+- protobuf-maven-plugin
+- ${plugin.protobuf.version}
+-
+-
+-
+- com.bazaarvoice.maven.plugins
+- s3-upload-maven-plugin
+- ${plugin.s3.upload.version}
+-
+-
+-
+- org.codehaus.mojo
+- buildnumber-maven-plugin
+- ${plugin.buildnumber.version}
+-
+-
+-
+- org.vafer
+- jdeb
+- ${plugin.jdeb.version}
+-
+-
+-
+- org.apache.avro
+- avro-maven-plugin
+- ${plugin.avro.version}
+-
+-
+-
+- org.scalatra.scalate
+- maven-scalate-plugin_${scala.binary.version}
+- ${plugin.scalate.version}
+-
+-
+-
+- org.scala-tools
+- maven-scala-plugin
+- ${plugin.scala.tools.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-source-plugin
+- ${plugin.source.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-javadoc-plugin
+- ${plugin.javadoc.version}
+-
+-
+-
+- org.apache.maven.plugins
+- maven-gpg-plugin
+- ${plugin.gpg.version}
+-
+-
+-
+- org.apache.rat
+- apache-rat-plugin
+- ${plugin.rat.version}
+-
+-
+-
+-
+-
+-
+-
+-
+- scala-2.10
+-
+- true
+-
+-
+- ${scala.2.10.version}
+- 2.10
+-
+-
+-
+-
+- scala-2.11
+-
+- ${scala.2.11.version}
+- 2.11
+-
+-
+-
+-
+- web-angular
+-
+- zeppelin-web-angular
+-
+-
+-
+-
+- vendor-repo
+-
+-
+- cloudera
+- https://repository.cloudera.com/artifactory/cloudera-repos/
+-
+-
+- hortonworks
+- https://repo.hortonworks.com/content/groups/public/
+-
+-
+-
+-
+-
+- integration
+-
+- zeppelin-integration
+- zeppelin-interpreter-integration
+-
+-
+-
+-
+- examples
+-
+- zeppelin-examples
+-
+-
+-
+-
+- helium-dev
+-
+- helium-dev
+-
+-
+-
+-
+- include-hadoop
+-
+- compile
+-
+-
+-
+-
+- build-distr
+-
+- false
+-
+-
++
+
+-
+-
+- org.apache.maven.plugins
+- maven-surefire-plugin
+-
+- true
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-assembly-plugin
+-
+-
+- make-assembly
+- package
+-
+- single
+-
+-
+-
+-
+-
+-
++
++
++ maven-dependency-plugin
++
++
++ copy-plugin-dependencies
++ package
++
++ copy-dependencies
++
++
++ ${project.basedir}/../../../plugins/${plugin.name}
++ false
++ false
++ true
++ runtime
++
++
++
++ copy-plugin-artifact
++ package
++
++ copy
++
++
++ ${project.basedir}/../../../plugins/${plugin.name}
++ false
++ false
++ true
++
++
++ ${project.groupId}
++ ${project.artifactId}
++ ${project.version}
++ ${project.packaging}
++
++
++
++
++
++
++
++ maven-clean-plugin
++
++
++ delete-plugin-dir
++
++ clean
++
++ clean
++
++
++
++ ${project.basedir}/../../../plugins/${plugin.name}
++ true
++ false
++
++
++
++
++
++
++
+
+-
+-
+-
+-
+- publish-distr
+-
+-
+-
+- org.apache.maven.plugins
+- maven-surefire-plugin
+-
+- true
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-source-plugin
+-
+-
+- attach-sources
+-
+- jar
+-
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-javadoc-plugin
+-
+-
+- attach-javadocs
+-
+- jar
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- release-sign-artifacts
+-
+-
+- performRelease
+- true
+-
+-
+-
+-
+-
+- org.apache.maven.plugins
+- maven-gpg-plugin
+-
+-
+- sign-artifacts
+- verify
+-
+- sign
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- rat
+-
+- !skipRat
+-
+-
+-
+-
+- org.apache.rat
+- apache-rat-plugin
+-
+-
+- **/*.keywords
+- reports/**
+- **/.idea/
+- **/*.iml
+- .git/
+- .github/*
+- .gitignore
+- git.properties
+- .repository/
+- .rat-excludes/
+- .Rhistory
+- **/*.diff
+- **/*.patch
+- **/*.avsc
+- **/*.avro
+- **/*.log
+- **/*.ipynb
+- **/test/resources/**
+- **/.settings/*
+- **/.factorypath
+- **/.classpath
+- **/.project
+- **/target/**
+- **/derby.log
+- **/metastore_db/
+- **/logs/**
+- **/run/**
+- **/interpreter/**
+- **/local-repo/**
+- **/null/**
+- **/notebook/**
+- _tools/site/css/*
+- _tools/maven-4.0.0.xsd
+- **/README.md
+- DEPENDENCIES
+- DEPLOY.md
+- STYLE.md
+- Roadmap.md
+- **/licenses/**
+- **/zeppelin-distribution/src/bin_license/**
+- conf/interpreter.json
+- conf/notebook-authorization.json
+- conf/credentials.json
+- conf/zeppelin-env.sh
+- conf/helium.json
+- spark-*-bin*/**
+- .spark-dist/**
+- **/interpreter-setting.json
+- **/constants.json
+- scripts/**
+- **/**/*.log
+- **/**/logs/**
+-
+-
+- **/test/karma.conf.js
+- **/test/spec/**
+- **/.babelrc
+- **/.bowerrc
+- .editorconfig
+- .eslintrc
+- protractor.conf.js
+- **/.tmp/**
+- **/target/**
+- **/node/**
+- **/node_modules/**
+- **/bower_components/**
+- **/dist/**
+- **/.buildignore
+- **/.npmignore
+- **/.jshintrc
+- **/yarn.lock
+- **/bower.json
+- **/src/fonts/Patua-One*
+- **/src/fonts/patua-one*
+- **/src/fonts/Roboto*
+- **/src/fonts/roboto*
+- **/src/fonts/fontawesome*
+- **/src/fonts/font-awesome*
+- **/src/styles/font-awesome*
+- **/src/fonts/Simple-Line*
+- **/src/fonts/simple-line*
+- **/src/fonts/Source-Code-Pro*
+- **/src/fonts/source-code-pro*
+- **/src/**/**.test.js
+- **/e2e/**/**.spec.js
+- package-lock.json
+-
+-
+- **/*.json
+- **/browserslist
+- **/.prettierrc
+- **/.prettierignore
+- **/.editorconfig
+- **/src/**/*.svg
+- **/.gitkeep
+-
+-
+-
+- **/src/main/java/org/apache/zeppelin/jdbc/SqlCompleter.java
+-
+-
+- docs/assets/themes/zeppelin/bootstrap/**
+- docs/assets/themes/zeppelin/css/style.css
+- docs/assets/themes/zeppelin/js/docs.js
+- docs/assets/themes/zeppelin/js/search.js
+- docs/_includes/themes/zeppelin/_jumbotron.html
+- docs/_includes/themes/zeppelin/_navigation.html
+-
+-
+- docs/404.html
+- docs/_config.yml
+- docs/_includes/JB/**
+- docs/_layouts/**
+- docs/_plugins/**
+- docs/atom.xml
+- docs/_includes/themes/zeppelin/default.html
+- docs/_includes/themes/zeppelin/page.html
+- docs/_includes/themes/zeppelin/post.html
+- docs/_includes/themes/zeppelin/settings.yml
+- docs/Rakefile
+- docs/rss.xml
+- docs/sitemap.txt
+- docs/search_data.json
+- **/dependency-reduced-pom.xml
+-
+-
+- docs/assets/themes/zeppelin/js/anchor.min.js
+-
+-
+- docs/assets/themes/zeppelin/js/toc.js
+-
+-
+- docs/assets/themes/zeppelin/js/lunr.min.js
+-
+-
+- docs/assets/themes/zeppelin/css/syntax.css
+-
+-
+- docs/_site/**
+- docs/Gemfile.lock
+-
+-
+- **/package.json
+-
+-
+- **/R/lib/**
+- **/lib/rzeppelin/**
+-
+-
+-
+- **/R/rzeppelin/R/*.R
+- **/src/main/scala/scala/Console.scala
+- **/src/main/scala/org/apache/zeppelin/rinterpreter/rscala/Package.scala
+- **/src/main/scala/org/apache/zeppelin/rinterpreter/rscala/RClient.scala
+-
+-
+- **/R/rzeppelin/DESCRIPTION
+- **/R/rzeppelin/NAMESPACE
+-
+- zeppelin-jupyter-interpreter/src/main/resources/grpc/jupyter/*.py
+-
+-
+-
+-
+-
+- verify.rat
+- verify
+-
+- check
+-
+-
+-
+-
+-
+-
+-
+-
+-
+- hadoop2
+-
+- ${hadoop2.7.version}
+- 2.13.0
+-
+-
+-
+-
+- hadoop3
+-
+- ${hadoop3.2.version}
+- 2.13.0
+- 2.0.0-M15
+-
+-
+-
+-
+-
++
+
+diff --git a/zeppelin-plugins/pom.xml b/zeppelin-plugins/pom.xml
+index cef5f418d..d9b3e806d 100644
+--- a/zeppelin-plugins/pom.xml
++++ b/zeppelin-plugins/pom.xml
+@@ -41,6 +41,7 @@
+
+
+ notebookrepo/s3
++ notebookrepo/opensearch
+ notebookrepo/github
+ notebookrepo/azure
+ notebookrepo/gcs
+diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
+index 2b3a24c9b..cb634e3b4 100644
+--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
++++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/search/LuceneSearch.java
+@@ -28,7 +28,6 @@ import java.util.Date;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.concurrent.TimeUnit;
+-import java.util.stream.Stream;
+ import javax.inject.Inject;
+
+ import org.apache.lucene.analysis.Analyzer;
+@@ -36,7 +35,7 @@ import org.apache.lucene.analysis.TokenStream;
+ import org.apache.lucene.analysis.standard.StandardAnalyzer;
+ import org.apache.lucene.document.Document;
+ import org.apache.lucene.document.Field;
+-import org.apache.lucene.document.LongField;
++import org.apache.lucene.document.LongPoint;
+ import org.apache.lucene.document.StringField;
+ import org.apache.lucene.document.TextField;
+ import org.apache.lucene.index.DirectoryReader;
+@@ -95,7 +94,7 @@ public class LuceneSearch extends SearchService {
+ logger.info("Use {} for storing lucene search index", this.indexPath);
+ } catch (IOException e) {
+ throw new RuntimeException(
+- "Failed to create index directory for search service. Use memory instead", e);
++ "Failed to create index directory for search service. Use memory instead", e);
+ }
+ } else {
+ this.indexDirectory = new RAMDirectory();
+@@ -116,14 +115,14 @@ public class LuceneSearch extends SearchService {
+ public List> query(String queryStr) {
+ if (null == indexDirectory) {
+ throw new IllegalStateException(
+- "Something went wrong on instance creation time, index dir is null");
++ "Something went wrong on instance creation time, index dir is null");
+ }
+ List> result = Collections.emptyList();
+ try (IndexReader indexReader = DirectoryReader.open(indexDirectory)) {
+ IndexSearcher indexSearcher = new IndexSearcher(indexReader);
+ Analyzer analyzer = new StandardAnalyzer();
+ MultiFieldQueryParser parser =
+- new MultiFieldQueryParser(new String[] {SEARCH_FIELD_TEXT, SEARCH_FIELD_TITLE}, analyzer);
++ new MultiFieldQueryParser(new String[] {SEARCH_FIELD_TEXT, SEARCH_FIELD_TITLE}, analyzer);
+
+ Query query = parser.parse(queryStr);
+ logger.debug("Searching for: " + query.toString(SEARCH_FIELD_TEXT));
+@@ -141,7 +140,7 @@ public class LuceneSearch extends SearchService {
+ }
+
+ private List> doSearch(
+- IndexSearcher searcher, Query query, Analyzer analyzer, Highlighter highlighter) {
++ IndexSearcher searcher, Query query, Analyzer analyzer, Highlighter highlighter) {
+ List> matchingParagraphs = Lists.newArrayList();
+ ScoreDoc[] hits;
+ try {
+@@ -165,8 +164,8 @@ public class LuceneSearch extends SearchService {
+
+ if (text != null) {
+ TokenStream tokenStream =
+- TokenSources.getTokenStream(
+- searcher.getIndexReader(), id, SEARCH_FIELD_TEXT, analyzer);
++ TokenSources.getTokenStream(
++ searcher.getIndexReader(), id, SEARCH_FIELD_TEXT, analyzer);
+ TextFragment[] frag = highlighter.getBestTextFragments(tokenStream, text, true, 3);
+ logger.debug(" {} fragments found for query '{}'", frag.length, query);
+ for (int j = 0; j < frag.length; j++) {
+@@ -179,17 +178,17 @@ public class LuceneSearch extends SearchService {
+
+ if (header != null) {
+ TokenStream tokenTitle =
+- TokenSources.getTokenStream(
+- searcher.getIndexReader(), id, SEARCH_FIELD_TITLE, analyzer);
++ TokenSources.getTokenStream(
++ searcher.getIndexReader(), id, SEARCH_FIELD_TITLE, analyzer);
+ TextFragment[] frgTitle = highlighter.getBestTextFragments(tokenTitle, header, true, 3);
+ header = (frgTitle != null && frgTitle.length > 0) ? frgTitle[0].toString() : "";
+ } else {
+ header = "";
+ }
+ matchingParagraphs.add(
+- ImmutableMap.of(
+- "id", path, // /paragraph/
+- "name", title, "snippet", fragment, "text", text, "header", header));
++ ImmutableMap.of(
++ "id", path, // /paragraph/
++ "name", title, "snippet", fragment, "text", text, "header", header));
+ } else {
+ logger.info("{}. No {} for this document", i + 1, ID_FIELD);
+ }
+@@ -293,7 +292,7 @@ public class LuceneSearch extends SearchService {
+ doc.add(new TextField(SEARCH_FIELD_TITLE, p.getTitle(), Field.Store.YES));
+ }
+ Date date = p.getDateStarted() != null ? p.getDateStarted() : p.getDateCreated();
+- doc.add(new LongField("modified", date.getTime(), Field.Store.NO));
++ doc.add(new LongPoint("modified", date.getTime()));
+ } else {
+ doc.add(new TextField(SEARCH_FIELD_TEXT, noteName, Field.Store.YES));
+ }
+@@ -322,9 +321,9 @@ public class LuceneSearch extends SearchService {
+ }
+ long end = System.nanoTime();
+ logger.info(
+- "Indexing {} notebooks took {}ms",
+- docsIndexed,
+- TimeUnit.NANOSECONDS.toMillis(end - start));
++ "Indexing {} notebooks took {}ms",
++ docsIndexed,
++ TimeUnit.NANOSECONDS.toMillis(end - start));
+ }
+ }
+
+@@ -377,14 +376,14 @@ public class LuceneSearch extends SearchService {
+
+ private void deleteDoc(String noteId, Paragraph p) {
+ String fullNoteOrJustParagraph = formatDeleteId(noteId, p);
+- logger.debug("Deleting note {}, out of: {}", noteId, indexWriter.numDocs());
++ logger.debug("Deleting note {}, out of: {}", noteId, indexWriter.getDocStats());
+ try {
+ indexWriter.deleteDocuments(new WildcardQuery(new Term(ID_FIELD, fullNoteOrJustParagraph)));
+ indexWriter.commit();
+ } catch (IOException e) {
+ logger.error("Failed to delete {} from index by '{}'", noteId, fullNoteOrJustParagraph, e);
+ }
+- logger.debug("Done, index contains {} docs now" + indexWriter.numDocs());
++ logger.debug("Done, index contains {} docs now" + indexWriter.getDocStats());
+ }
+
+ /* (non-Javadoc)
+@@ -415,28 +414,22 @@ public class LuceneSearch extends SearchService {
+
+ /** Indexes a single document: - code of the paragraph (if non-null) - or just a note name */
+ private void indexDoc(IndexWriter w, String noteId, String noteName, Paragraph p)
+- throws IOException {
++ throws IOException {
+ String id = formatId(noteId, p);
+ Document doc = newDocument(id, noteName, p);
+ w.addDocument(doc);
+ }
+
+ @Override
+- public void startRebuildIndex(Stream notes) {
++ public void startRebuildIndex(List notes) {
+ Thread thread = new Thread(() -> {
+ logger.info("Starting rebuild index");
+- notes.forEach(note -> {
++ for (Note note: notes) {
+ addIndexDoc(note);
+- note.unLoad();
+- });
++ }
+ logger.info("Finish rebuild index");
+ });
+ thread.setName("LuceneSearch-RebuildIndex-Thread");
+ thread.start();
+- try {
+- thread.join();
+- } catch (InterruptedException e) {
+- e.printStackTrace();
+- }
+ }
+ }
+
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/pom.xml b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/pom.xml
new file mode 100644
index 000000000..f74423050
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/pom.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ 4.0.0
+
+ zengine-plugins-parent
+ org.apache.zeppelin
+ 0.9.0-SNAPSHOT
+ ../../../zeppelin-plugins
+
+
+ org.apache.zeppelin
+ notebookrepo-opensearch
+ jar
+ 0.9.0-SNAPSHOT
+ Zeppelin: Plugin OpenSearchNotebookRepo
+ NotebookRepo implementation based on OpenSearch
+
+
+ 7.8.0
+ NotebookRepo/OpenSearchNotebookRepo
+ true
+
+
+
+
+ org.opensearch.client
+ elasticsearch-rest-high-level-client
+ ${elasticsearch.client.version}
+
+
+ org.apache.logging.log4j
+ log4j-to-slf4j
+ 2.11.1
+
+
+
+
+
+
+ maven-dependency-plugin
+
+
+
+
diff --git a/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/src/main/java/org/apache/zeppelin/notebook/repo/OpenSearchNotebookRepo.java b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/src/main/java/org/apache/zeppelin/notebook/repo/OpenSearchNotebookRepo.java
new file mode 100644
index 000000000..4405c3a6f
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/docs/poc/zeppelin/zeppelin-plugins/notebookrepo/opensearch/src/main/java/org/apache/zeppelin/notebook/repo/OpenSearchNotebookRepo.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.apache.zeppelin.notebook.repo;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.NoteInfo;
+import org.apache.zeppelin.user.AuthenticationInfo;
+import org.opensearch.ElasticsearchStatusException;
+import org.opensearch.action.DocWriteResponse;
+import org.opensearch.action.delete.DeleteRequest;
+import org.opensearch.action.delete.DeleteResponse;
+import org.opensearch.action.get.GetRequest;
+import org.opensearch.action.get.GetResponse;
+import org.opensearch.action.index.IndexRequest;
+import org.opensearch.action.index.IndexResponse;
+import org.opensearch.action.search.SearchRequest;
+import org.opensearch.action.search.SearchResponse;
+import org.opensearch.client.RequestOptions;
+import org.opensearch.client.RestClient;
+import org.opensearch.client.RestClientBuilder;
+import org.opensearch.client.RestHighLevelClient;
+import org.opensearch.client.indices.CreateIndexRequest;
+import org.opensearch.client.indices.CreateIndexResponse;
+import org.opensearch.common.xcontent.XContentType;
+import org.opensearch.index.query.QueryBuilders;
+import org.opensearch.search.SearchHit;
+import org.opensearch.search.SearchHits;
+import org.opensearch.search.builder.SearchSourceBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Backend for storing Notebooks on OpenSearch
+ */
+public class OpenSearchNotebookRepo implements NotebookRepo {
+ private static final Logger LOGGER = LoggerFactory.getLogger(OpenSearchNotebookRepo.class);
+
+//
+
+ private RestHighLevelClient OpenSearchClient;
+ private String user;
+ private String password;
+ private String host;
+ private Integer port;
+ private String protocol;
+ private String rootIndex = ".notebooks";
+ private ZeppelinConfiguration conf;
+
+ public OpenSearchNotebookRepo() {
+
+ }
+
+ private RestHighLevelClient client() {
+ // Uncomment to add path for ssl keystore and using https client
+ // Discussion on generating keystore with certificate: https://github.com/opendistro-for-elasticsearch/community/issues/64#issuecomment-493258442
+ // System.setProperty("javax.net.ssl.trustStore", "/path/to/keystore/keystore.jks");
+ final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
+
+ RestHighLevelClient client = new RestHighLevelClient(
+ RestClient.builder(
+ new HttpHost(host, port, protocol)).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+ @Override
+ public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+ return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+ }
+ }));
+ return client;
+ }
+
+ private void CreateNotebooksIndex() throws IOException {
+ CreateIndexRequest request = new CreateIndexRequest(rootIndex);
+ try {
+ CreateIndexResponse createIndexResponse = OpenSearchClient.indices().create(request, RequestOptions.DEFAULT);
+ } catch (ElasticsearchStatusException e) {
+ if (!e.getMessage().contains("resource_already_exists_exception")) {
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public void init(ZeppelinConfiguration conf) throws IOException {
+ this.conf = conf;
+ // Change Client configuration here
+ user = "admin";
+ password = "admin";
+ host = "localhost";
+ port = 9200;
+ protocol = "http";
+ OpenSearchClient = client();
+ CreateNotebooksIndex();
+ }
+
+
+ @Override
+ public Map list(AuthenticationInfo subject) throws IOException {
+ Map notesInfo = new HashMap<>();
+ SearchRequest searchRequest = new SearchRequest(rootIndex);
+ SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
+ searchSourceBuilder.query(QueryBuilders.matchAllQuery());
+ searchRequest.source(searchSourceBuilder);
+ SearchResponse searchResponse = OpenSearchClient.search(searchRequest, RequestOptions.DEFAULT);
+
+ SearchHits hits = searchResponse.getHits();
+
+ if (hits.getHits().length>0) {
+ SearchHit[] searchHits = hits.getHits();
+ for (SearchHit hit : searchHits) {
+ Map noteJson = hit.getSourceAsMap();
+ NoteInfo noteInfo = new NoteInfo(noteJson.get("id").toString(), noteJson.get("path").toString());
+ notesInfo.put(noteJson.get("id").toString(), noteInfo);
+ }
+ }
+ return notesInfo;
+ }
+
+
+ @Override
+ public Note get(String noteId, String notePath, AuthenticationInfo subject) throws IOException {
+ GetRequest getRequest = new GetRequest(rootIndex, noteId);
+ GetResponse getResponse = OpenSearchClient.get(getRequest, RequestOptions.DEFAULT);
+ if (getResponse.isExists()) {
+ String json = getResponse.getSourceAsString();
+ return Note.fromJson(json);
+ } else {
+ throw new IOException("Note '" + noteId + "' in path '" + notePath + "'not found in OpenSearch");
+ }
+ }
+
+ @Override
+ public void save(Note note, AuthenticationInfo subject) throws IOException {
+ // TODO: Other NotebookRepos deal with File paths as a separate kept entity
+ // They don't store path in the notebook itself
+ // Here, we merge path as a notebook property
+ // In the later release we need to decouple this to support folder structures
+
+ JsonObject json = new JsonParser().parse(note.toJson()).getAsJsonObject();
+ json.addProperty("path",note.getPath());
+ try {
+ IndexRequest request = new IndexRequest(rootIndex);
+ request.id(note.getId());
+ request.source(json.toString(), XContentType.JSON);
+ IndexResponse indexResponse = OpenSearchClient.index(request, RequestOptions.DEFAULT);
+ } catch (IOException e) {
+ throw new IOException("Fail to store note: " + note.getPath() + " in OpenSearch", e);
+ }
+ }
+
+ @Override
+ public void move(String noteId, String notePath, String newNotePath,
+ AuthenticationInfo subject) throws IOException {
+ LOGGER.warn("Method not implemented");
+ }
+
+ @Override
+ public void move(String folderPath, String newFolderPath, AuthenticationInfo subject) throws IOException {
+ LOGGER.warn("Method not implemented");
+ }
+
+ @Override
+ public void remove(String noteId, String notePath, AuthenticationInfo subject)
+ throws IOException {
+ DeleteRequest request = new DeleteRequest(rootIndex, noteId);
+ DeleteResponse deleteResponse = OpenSearchClient.delete(request, RequestOptions.DEFAULT);
+ if (deleteResponse.getResult() != DocWriteResponse.Result.NOT_FOUND) {
+ System.out.println(deleteResponse.toString());
+ } else {
+ throw new IOException("Note '" + noteId + "' in path '" + notePath + "'cannot be deleted");
+ }
+ }
+
+ @Override
+ public void remove(String folderPath, AuthenticationInfo subject) throws IOException {
+ LOGGER.warn("Method not implemented");
+ }
+
+ @Override
+ public void close() {
+ try {
+ OpenSearchClient.close();
+ } catch (IOException exception) {
+ exception.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public List getSettings(AuthenticationInfo subject) {
+ LOGGER.warn("Method not implemented");
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void updateSettings(Map settings, AuthenticationInfo subject) {
+ LOGGER.warn("Method not implemented");
+ }
+
+}
+
diff --git a/dashboards-observability/public/components/notebooks/index.scss b/dashboards-observability/public/components/notebooks/index.scss
new file mode 100644
index 000000000..d21d4c866
--- /dev/null
+++ b/dashboards-observability/public/components/notebooks/index.scss
@@ -0,0 +1,39 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+.editorArea {
+ font-family: Dank Mono, Source Code Pro, Consolas, Courier New, Courier, monospace;
+ font-size: 1em;
+ border: none;
+ width: 100%;
+ height: 14em;
+}
+
+#notebookArea {
+ max-width: 88vw;
+}
+
+.panel-header-count {
+ color: #687078;
+ font-weight: normal;
+}
+
+.markdown-output-text {
+ font-family: 'Inter UI', -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif,
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
+}
+
+.notebooks-paragraph button[aria-label='Expand'] {
+ display: none;
+}
+.notebooks-paragraph-dark .markdown-body {
+ pre.input {
+ background-color: #25262d !important;
+ }
+ code.language-text {
+ color: #e0e5ee !important;
+ background-color: #25262d !important;
+ }
+}
diff --git a/public/components/common/__tests__/__snapshots__/helper_functions.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/__tests__/__snapshots__/helper_functions.test.tsx.snap
similarity index 100%
rename from public/components/common/__tests__/__snapshots__/helper_functions.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/__tests__/__snapshots__/helper_functions.test.tsx.snap
diff --git a/public/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap
similarity index 98%
rename from public/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap
index d8be845df..1667bfcc8 100644
--- a/public/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/common/__tests__/__snapshots__/search_bar.test.tsx.snap
@@ -46,7 +46,7 @@ exports[`Search bar components renders date picker 1`] = `
},
]
}
- dateFormat="MMM D, YYYY @ HH:mm:ss.SSS"
+ dateFormat=""
end="now"
isAutoRefreshOnly={false}
isDisabled={false}
@@ -120,7 +120,7 @@ exports[`Search bar components renders date picker 1`] = `
},
]
}
- dateFormat="MMM D, YYYY @ HH:mm:ss.SSS"
+ dateFormat=""
end="now"
isAutoRefreshOnly={false}
isDisabled={false}
@@ -181,7 +181,7 @@ exports[`Search bar components renders date picker 1`] = `
},
]
}
- dateFormat="MMM D, YYYY @ HH:mm:ss.SSS"
+ dateFormat=""
end="now"
isAutoRefreshOnly={false}
isDisabled={false}
@@ -382,6 +382,7 @@ exports[`Search bar components renders date picker 1`] = `
exports[`Search bar components renders search bar 1`] = `
{
configure({ adapter: new Adapter() });
@@ -64,8 +43,11 @@ describe('Helper functions', () => {
});
it('renders benchmark', () => {
+ // @ts-ignore
const benchmarkPositive = mount(renderBenchmark(50));
+ // @ts-ignore
const benchmarkNegative = mount(renderBenchmark(-50));
+ // @ts-ignore
const benchmarkZero = mount(renderBenchmark(0));
expect(benchmarkPositive).toMatchSnapshot();
expect(benchmarkNegative).toMatchSnapshot();
@@ -77,8 +59,10 @@ describe('Helper functions', () => {
expect(ms).toEqual(123.456789);
const ns = milliToNanoSec(123.456789);
expect(ns).toEqual(123456789);
+ // @ts-ignore
const invalidMs = nanoToMilliSec('abc');
expect(invalidMs).toEqual(0);
+ // @ts-ignore
const invalidNs = milliToNanoSec('abc');
expect(invalidNs).toEqual(0);
});
@@ -134,30 +118,31 @@ describe('Helper functions', () => {
});
it('converts filters to DSL', () => {
- const getTestFilters = (field = 'traceGroup', operator = 'exists') => [
- [
- {
- field,
- operator,
- value: { from: '100', to: '\u221E' },
- inverted: false,
- disabled: false,
- },
- ],
- 'order',
- 'now-5m',
- 'now',
- ];
- const existsDSL = filtersToDsl(...getTestFilters());
+ const getTestDslFromFilters = (field = 'traceGroup', operator = 'exists') =>
+ filtersToDsl(
+ [
+ {
+ field,
+ operator,
+ value: { from: '100', to: '\u221E' },
+ inverted: false,
+ disabled: false,
+ },
+ ],
+ 'order',
+ 'now-5m',
+ 'now'
+ );
+ const existsDSL = getTestDslFromFilters();
expect(JSON.stringify(existsDSL)).toEqual(
- "{\"query\":{\"bool\":{\"must\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}},{\"query_string\":{\"query\":\"order\"}},{\"exists\":{\"field\":\"traceGroup\"}}],\"filter\":[],\"should\":[],\"must_not\":[]}},\"custom\":{\"timeFilter\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}}],\"serviceNames\":[],\"serviceNamesExclude\":[],\"traceGroup\":[],\"traceGroupExclude\":[],\"percentiles\":{\"query\":{\"bool\":{\"should\":[]}}}}}"
+ '{"query":{"bool":{"must":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}},{"query_string":{"query":"order"}},{"exists":{"field":"traceGroup"}}],"filter":[],"should":[],"must_not":[]}},"custom":{"timeFilter":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}}],"serviceNames":[],"serviceNamesExclude":[],"traceGroup":[],"traceGroupExclude":[],"percentiles":{"query":{"bool":{"should":[]}}}}}'
);
- const isDSL = filtersToDsl(...getTestFilters('traceGroup', 'is'));
+ const isDSL = getTestDslFromFilters('traceGroup', 'is');
expect(JSON.stringify(isDSL)).toEqual(
- "{\"query\":{\"bool\":{\"must\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}},{\"query_string\":{\"query\":\"order\"}},{\"term\":{\"traceGroup\":{\"from\":\"100\",\"to\":\"∞\"}}}],\"filter\":[],\"should\":[],\"must_not\":[]}},\"custom\":{\"timeFilter\":[{\"range\":{\"startTime\":{\"gte\":\"now-5m\",\"lte\":\"now\"}}}],\"serviceNames\":[],\"serviceNamesExclude\":[],\"traceGroup\":[],\"traceGroupExclude\":[],\"percentiles\":{\"query\":{\"bool\":{\"should\":[]}}}}}"
+ '{"query":{"bool":{"must":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}},{"query_string":{"query":"order"}},{"term":{"traceGroup":{"from":"100","to":"∞"}}}],"filter":[],"should":[],"must_not":[]}},"custom":{"timeFilter":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}}],"serviceNames":[],"serviceNamesExclude":[],"traceGroup":[],"traceGroupExclude":[],"percentiles":{"query":{"bool":{"should":[]}}}}}'
);
- const isBetweenDSL = filtersToDsl(...getTestFilters('durationInNanos', 'is between'));
+ const isBetweenDSL = getTestDslFromFilters('durationInNanos', 'is between');
expect(JSON.stringify(isBetweenDSL)).toEqual(
`{"query":{"bool":{"must":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}},{"query_string":{"query":"order"}},{"range":{"durationInNanos":{"gte":"100"}}}],"filter":[],"should":[],"must_not":[]}},"custom":{"timeFilter":[{"range":{"startTime":{"gte":"now-5m","lte":"now"}}}],"serviceNames":[],"serviceNamesExclude":[],"traceGroup":[],"traceGroupExclude":[],"percentiles":{"query":{"bool":{"should":[]}}}}}`
);
diff --git a/public/components/common/__tests__/search_bar.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/__tests__/search_bar.test.tsx
similarity index 56%
rename from public/components/common/__tests__/search_bar.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/__tests__/search_bar.test.tsx
index 79bf43698..9e0c8ed12 100644
--- a/public/components/common/__tests__/search_bar.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/__tests__/search_bar.test.tsx
@@ -1,35 +1,13 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
*/
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-import React from 'react';
-import { render } from '@testing-library/react';
-import { configure, mount, shallow } from 'enzyme';
+import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
-import { renderDatePicker, SearchBar } from '..';
+import React from 'react';
import sinon from 'sinon';
+import { renderDatePicker, SearchBar } from '../search_bar';
describe('Search bar components', () => {
configure({ adapter: new Adapter() });
@@ -61,6 +39,7 @@ describe('Search bar components', () => {
setEndTime={setEndTime}
filters={[]}
setFilters={setFilters}
+ appConfigs={[]}
/>
);
expect(wrapper).toMatchSnapshot();
diff --git a/public/components/common/color_palette.ts b/dashboards-observability/public/components/trace_analytics/components/common/color_palette.ts
similarity index 87%
rename from public/components/common/color_palette.ts
rename to dashboards-observability/public/components/trace_analytics/components/common/color_palette.ts
index cebaeeb26..e07be70f9 100644
--- a/public/components/common/color_palette.ts
+++ b/dashboards-observability/public/components/trace_analytics/components/common/color_palette.ts
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
export const serviceMapColorPalette = {
diff --git a/public/components/common/filters/__tests__/__snapshots__/filter_edit_popover.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filter_edit_popover.test.tsx.snap
similarity index 100%
rename from public/components/common/filters/__tests__/__snapshots__/filter_edit_popover.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filter_edit_popover.test.tsx.snap
diff --git a/public/components/common/filters/__tests__/__snapshots__/filter_helpers.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filter_helpers.test.tsx.snap
similarity index 100%
rename from public/components/common/filters/__tests__/__snapshots__/filter_helpers.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filter_helpers.test.tsx.snap
diff --git a/public/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap
similarity index 99%
rename from public/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap
index d21333e17..811b7c5c9 100644
--- a/public/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/common/filters/__tests__/__snapshots__/filters.test.tsx.snap
@@ -2,6 +2,7 @@
exports[`Filter component renders filters 1`] = `
{
+ configure({ adapter: new Adapter() });
+
+ it('renders filters', () => {
+ const setFilters = jest.fn();
+ const wrapper = mount(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/public/components/common/filters/filter_edit_popover.tsx b/dashboards-observability/public/components/trace_analytics/components/common/filters/filter_edit_popover.tsx
similarity index 83%
rename from public/components/common/filters/filter_edit_popover.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/filter_edit_popover.tsx
index 7959bf170..7f0882739 100644
--- a/public/components/common/filters/filter_edit_popover.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/filters/filter_edit_popover.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
diff --git a/public/components/common/filters/filter_helpers.tsx b/dashboards-observability/public/components/trace_analytics/components/common/filters/filter_helpers.tsx
similarity index 83%
rename from public/components/common/filters/filter_helpers.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/filter_helpers.tsx
index e9397315d..1410bfea0 100644
--- a/public/components/common/filters/filter_helpers.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/filters/filter_helpers.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
@@ -34,22 +13,23 @@ import {
import _ from 'lodash';
import React from 'react';
-const getFields = (page: 'dashboard' | 'traces' | 'services') =>
+const getFields = (page: 'dashboard' | 'traces' | 'services' | 'app') =>
({
dashboard: ['traceGroup', 'serviceName', 'error', 'status.message', 'latency'],
traces: ['traceId', 'traceGroup', 'serviceName', 'error', 'status.message', 'latency'],
services: ['traceGroup', 'serviceName', 'error', 'status.message', 'latency'],
+ app: ['traceId', 'traceGroup', 'serviceName'],
}[page]);
// filters will take effect and can be manually added
-export const getFilterFields = (page: 'dashboard' | 'traces' | 'services') => getFields(page);
+export const getFilterFields = (page: 'dashboard' | 'traces' | 'services' | 'app') => getFields(page);
// filters will take effect
-export const getValidFilterFields = (page: 'dashboard' | 'traces' | 'services') => {
+export const getValidFilterFields = (page: 'dashboard' | 'traces' | 'services' | 'app') => {
const fields = getFields(page);
if (page !== 'services') return [...fields, 'Latency percentile within trace group'];
return fields;
};
-const getType = (field: string): string => {
+const getType = (field: string): string | null => {
const typeMapping = {
attributes: {
host: {
@@ -127,7 +107,7 @@ export const getOperatorOptions = (field: string) => {
};
const operators = [
...operatorMapping.default_first,
- ...operatorMapping[type],
+ ..._.get(operatorMapping, type),
...operatorMapping.default_last,
];
return operators;
diff --git a/public/components/common/filters/filters.tsx b/dashboards-observability/public/components/trace_analytics/components/common/filters/filters.tsx
similarity index 89%
rename from public/components/common/filters/filters.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/filters/filters.tsx
index 075fdd39c..d5a296b15 100644
--- a/public/components/common/filters/filters.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/filters/filters.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
@@ -37,7 +16,7 @@ import {
EuiPopoverTitle,
EuiTextColor,
} from '@elastic/eui';
-import React, { Dispatch, SetStateAction, useMemo, useState } from 'react';
+import React, { useMemo, useState } from 'react';
import { FilterEditPopover } from './filter_edit_popover';
import { getFilterFields, getValidFilterFields } from './filter_helpers';
@@ -53,11 +32,12 @@ export interface FilterType {
export interface FiltersProps {
filters: FilterType[];
- setFilters: Dispatch>;
+ appConfigs?: FilterType[];
+ setFilters: (filters: FilterType[]) => void;
}
interface FiltersOwnProps extends FiltersProps {
- page: 'dashboard' | 'traces' | 'services';
+ page: 'dashboard' | 'traces' | 'services' | 'app';
}
export function Filters(props: FiltersOwnProps) {
@@ -179,7 +159,7 @@ export function Filters(props: FiltersOwnProps) {
},
{
name: 'Delete',
- icon: ,
+ icon: ,
onClick: () => setFilter(null, index),
},
],
@@ -292,6 +272,7 @@ export function Filters(props: FiltersOwnProps) {
setFilter(null, index);
}}
iconOnClickAriaLabel="Remove filter"
+ data-test-subj="filterBadge"
>
{filterLabel}
@@ -299,6 +280,7 @@ export function Filters(props: FiltersOwnProps) {
return (
setIsPopoverOpen(false)}
panelPaddingSize="none"
diff --git a/public/components/common/helper_functions.tsx b/dashboards-observability/public/components/trace_analytics/components/common/helper_functions.tsx
similarity index 76%
rename from public/components/common/helper_functions.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/helper_functions.tsx
index 039dd4e2f..5bd437df8 100644
--- a/public/components/common/helper_functions.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/helper_functions.tsx
@@ -1,34 +1,20 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
+/* eslint-disable radix */
import dateMath from '@elastic/datemath';
import { EuiButton, EuiEmptyPrompt, EuiSpacer, EuiText } from '@elastic/eui';
import { SpacerSize } from '@elastic/eui/src/components/spacer/spacer';
+import { isEmpty, round } from 'lodash';
import React from 'react';
-import { DOCUMENTATION_LINK, RAW_INDEX_NAME, SERVICE_MAP_INDEX_NAME } from '../../../common';
+import {
+ DATA_PREPPER_INDEX_NAME,
+ DATA_PREPPER_SERVICE_INDEX_NAME,
+ TRACE_ANALYTICS_DOCUMENTATION_LINK,
+} from '../../../../../common/constants/trace_analytics';
+import { uiSettingsService } from '../../../../../common/utils';
import { serviceMapColorPalette } from './color_palette';
import { FilterType } from './filters/filters';
import { ServiceObject } from './plots/service_map';
@@ -69,7 +55,7 @@ export function MissingConfigurationMessage() {
title={Trace Analytics not set up }
body={
- {`The indices required for trace analytics (${RAW_INDEX_NAME} and ${SERVICE_MAP_INDEX_NAME}) do not exist or you do not have permission to access them.`}
+ {`The indices required for trace analytics (${DATA_PREPPER_INDEX_NAME} and ${DATA_PREPPER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`}
}
actions={
@@ -77,7 +63,7 @@ export function MissingConfigurationMessage() {
color="primary"
iconSide="right"
iconType="popout"
- onClick={() => window.open(DOCUMENTATION_LINK, '_blank')}
+ onClick={() => window.open(TRACE_ANALYTICS_DOCUMENTATION_LINK, '_blank')}
>
Learn more
@@ -108,14 +94,17 @@ export function milliToNanoSec(ms: number) {
return ms * 1000000;
}
-export function getServiceMapScaleColor(percent, idSelected) {
+export function getServiceMapScaleColor(
+ percent: number,
+ idSelected: 'latency' | 'error_rate' | 'throughput'
+) {
return serviceMapColorPalette[idSelected][Math.min(99, Math.max(0, Math.floor(percent * 100)))];
}
// construct vis-js graph from ServiceObject
export function getServiceMapGraph(
map: ServiceObject,
- idSelected: string,
+ idSelected: 'latency' | 'error_rate' | 'throughput',
ticks: number[],
currService?: string,
relatedServices?: string[]
@@ -130,7 +119,13 @@ export function getServiceMapGraph(
const color = getServiceMapScaleColor(percent, idSelected);
styleOptions = {
borderWidth: 0,
- color: relatedServices.indexOf(service) >= 0 ? `rgba(${color}, 1)` : `rgba(${color}, 0.3)`,
+ color: relatedServices!.indexOf(service) >= 0 ? `rgba(${color}, 1)` : `rgba(${color}, 0.2)`,
+ font: {
+ color:
+ relatedServices!.indexOf(service) >= 0
+ ? `rgba(72, 122, 180, 1)`
+ : `rgba(72, 122, 180, 0.2)`,
+ },
};
} else {
// service nodes that are not matched under traceGroup filter
@@ -147,47 +142,53 @@ export function getServiceMapGraph(
};
}
- const message =
- { latency: 'Average latency: ', error_rate: 'Error rate: ', throughput: 'Throughput: ' }[
- idSelected
- ] +
- (value >= 0
- ? value + (idSelected === 'latency' ? 'ms' : idSelected === 'error_rate' ? '%' : '')
- : 'N/A');
+ let hover = service;
+ hover += `\n\nAverage latency: ${
+ map[service].latency! >= 0 ? map[service].latency + 'ms' : 'N/A'
+ }`;
+ hover += `\nError rate: ${
+ map[service].error_rate! >= 0 ? map[service].error_rate + '%' : 'N/A'
+ }`;
+ hover += `\nThroughput: ${map[service].throughput! >= 0 ? map[service].throughput : 'N/A'}`;
+ if (map[service].throughputPerMinute != null)
+ hover += ` (${map[service].throughputPerMinute} per minute)`;
return {
id: map[service].id,
label: service,
size: service === currService ? 30 : 15,
- title: `${service}
${message}
`,
+ title: hover,
...styleOptions,
};
});
- const edges = [];
+ const edges: Array<{ from: number; to: number; color: string }> = [];
+ const edgeColor = uiSettingsService.get('theme:darkMode') ? '255, 255, 255' : '0, 0, 0';
Object.keys(map).map((service) => {
- map[service].targetServices.map((target) => {
- edges.push({
- from: map[service].id,
- to: map[target].id,
- color:
- relatedServices.indexOf(service) >= 0 && relatedServices.indexOf(target) >= 0
- ? 'rgba(0, 0, 0, 1)'
- : 'rgba(0, 0, 0, 0.3)',
+ map[service].targetServices
+ .filter((target) => map[target])
+ .map((target) => {
+ edges.push({
+ from: map[service].id,
+ to: map[target].id,
+ color:
+ relatedServices!.indexOf(service) >= 0 && relatedServices!.indexOf(target) >= 0
+ ? `rgba(${edgeColor}, 1)`
+ : `rgba(${edgeColor}, 0.2)`,
+ });
});
- });
});
return { graph: { nodes, edges } };
}
// returns flattened targetResource as an array for all traceGroups
export function getServiceMapTargetResources(map: ServiceObject, serviceName: string) {
- return [].concat.apply(
+ return ([] as string[]).concat.apply(
[],
[...map[serviceName].traceGroups.map((traceGroup) => [...traceGroup.targetResource])]
);
}
-export function calculateTicks(min, max, numTicks = 5) {
+export function calculateTicks(min: number, max: number, numTicks = 5): number[] {
if (min >= max) return calculateTicks(0, Math.max(1, max), numTicks);
min = Math.floor(min);
max = Math.ceil(max);
@@ -205,7 +206,7 @@ export function calculateTicks(min, max, numTicks = 5) {
let curr = Math.max(0, Math.floor((min - 1) / tick) * tick);
const ticks = [curr];
while (curr < max) {
- curr += tick;
+ curr = round(curr + tick, 1);
ticks.push(curr);
}
@@ -215,8 +216,8 @@ export function calculateTicks(min, max, numTicks = 5) {
// calculates the minimum fixed_interval for date_histogram from time filter
export const minFixedInterval = (startTime: string, endTime: string) => {
if (startTime?.length === 0 || endTime?.length === 0 || startTime === endTime) return '1d';
- const momentStart = dateMath.parse(startTime);
- const momentEnd = dateMath.parse(endTime);
+ const momentStart = dateMath.parse(startTime)!;
+ const momentEnd = dateMath.parse(endTime)!;
const diffSeconds = momentEnd.unix() - momentStart.unix();
if (diffSeconds <= 1) return '1ms'; // less than 1 second
@@ -251,7 +252,7 @@ export const getPercentileFilter = (
percentileMaps: Array<{ traceGroupName: string; durationFilter: { gte?: number; lte?: number } }>,
conditionString: string // >= 95th, < 95th
): FilterType => {
- const DSL = {
+ const DSL: any = {
query: {
bool: {
must: [],
@@ -268,7 +269,7 @@ export const getPercentileFilter = (
must: [
{
term: {
- 'traceGroup': {
+ traceGroup: {
value: map.traceGroupName,
},
},
@@ -296,7 +297,9 @@ export const filtersToDsl = (
filters: FilterType[],
query: string,
startTime: string,
- endTime: string
+ endTime: string,
+ page?: string,
+ appConfigs: FilterType[] = []
) => {
const DSL: any = {
query: {
@@ -408,5 +411,21 @@ export const filtersToDsl = (
DSL.query.bool[filter.inverted ? 'must_not' : 'must'].push(filterQuery);
});
+ if (page === 'app' && !isEmpty(appConfigs)) {
+ DSL.query.bool.minimum_should_match = 1;
+ appConfigs.forEach((config) => {
+ let appQuery = {};
+ const appField = config.field;
+ const appValue = config.value;
+ appQuery = {
+ term: {
+ [appField]: appValue,
+ },
+ };
+ DSL.query.bool.minimum_should_match = 1;
+ DSL.query.bool.should.push(appQuery);
+ });
+ }
+
return DSL;
};
diff --git a/public/components/common/plots/__tests__/__snapshots__/box_plt.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/box_plt.test.tsx.snap
similarity index 100%
rename from public/components/common/plots/__tests__/__snapshots__/box_plt.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/box_plt.test.tsx.snap
diff --git a/public/components/common/plots/__tests__/__snapshots__/error_rate_plt_.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/error_rate_plt_.test.tsx.snap
similarity index 100%
rename from public/components/common/plots/__tests__/__snapshots__/error_rate_plt_.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/error_rate_plt_.test.tsx.snap
diff --git a/public/components/common/plots/__tests__/__snapshots__/latency_trend_plt.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/latency_trend_plt.test.tsx.snap
similarity index 100%
rename from public/components/common/plots/__tests__/__snapshots__/latency_trend_plt.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/latency_trend_plt.test.tsx.snap
diff --git a/public/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap
similarity index 100%
rename from public/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map.test.tsx.snap
diff --git a/public/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap
similarity index 97%
rename from public/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap
index 6223a3d6e..f89aac7e8 100644
--- a/public/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/__snapshots__/service_map_scale.test.tsx.snap
@@ -163,6 +163,7 @@ exports[`Service map scale component renders service map scale plot 1`] = `
]
}
debug={false}
+ divId="explorerPlotComponent"
layout={
Object {
"autosize": true,
@@ -239,6 +240,7 @@ exports[`Service map scale component renders service map scale plot 1`] = `
useResizeHandler={true}
>
{
+ configure({ adapter: new Adapter() });
+
+ it('renders box plot', () => {
+ const addFilter = jest.fn();
+ const wrapper = shallow(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/public/components/common/plots/__tests__/error_rate_plt_.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/error_rate_plt_.test.tsx
similarity index 56%
rename from public/components/common/plots/__tests__/error_rate_plt_.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/error_rate_plt_.test.tsx
index a12dc3cd3..3203fbe82 100644
--- a/public/components/common/plots/__tests__/error_rate_plt_.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/error_rate_plt_.test.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import React from 'react';
diff --git a/public/components/common/plots/__tests__/latency_trend_plt.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/latency_trend_plt.test.tsx
similarity index 68%
rename from public/components/common/plots/__tests__/latency_trend_plt.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/latency_trend_plt.test.tsx
index 967ade894..ee5d786e9 100644
--- a/public/components/common/plots/__tests__/latency_trend_plt.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/latency_trend_plt.test.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import React from 'react';
diff --git a/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map.test.tsx
new file mode 100644
index 000000000..b7d505fb8
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map.test.tsx
@@ -0,0 +1,27 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { TEST_SERVICE_MAP } from '../../../../../../../test/constants';
+import { ServiceMap } from '../service_map';
+
+describe('Service map component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders service map', async () => {
+ const setServiceMapIdSelected = jest.fn((e) => {});
+ const wrapper = shallow(
+
+ );
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map_scale.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map_scale.test.tsx
new file mode 100644
index 000000000..811cc1920
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/service_map_scale.test.tsx
@@ -0,0 +1,26 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { render } from '@testing-library/react';
+import { configure, mount, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { ServiceMapScale } from '../service_map_scale';
+
+describe('Service map scale component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders service map scale plot', () => {
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/public/components/common/plots/__tests__/throughput_plt.test.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/throughput_plt.test.tsx
similarity index 56%
rename from public/components/common/plots/__tests__/throughput_plt.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/throughput_plt.test.tsx
index 1c693cd26..c5f8d1b0f 100644
--- a/public/components/common/plots/__tests__/throughput_plt.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/__tests__/throughput_plt.test.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import React from 'react';
diff --git a/public/components/common/plots/box_plt.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/box_plt.tsx
similarity index 83%
rename from public/components/common/plots/box_plt.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/box_plt.tsx
index 060ae5df8..d3c04f1cb 100644
--- a/public/components/common/plots/box_plt.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/box_plt.tsx
@@ -1,32 +1,11 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import { EuiFlexGrid, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui';
import React, { useMemo, useState } from 'react';
-import { Plt } from './plt';
+import { Plt } from '../../../../visualizations/plotly/plot';
interface PlotParamsType {
min: number;
diff --git a/public/components/common/plots/error_rate_plt.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/error_rate_plt.tsx
similarity index 66%
rename from public/components/common/plots/error_rate_plt.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/error_rate_plt.tsx
index 7b4a93883..748624536 100644
--- a/public/components/common/plots/error_rate_plt.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/error_rate_plt.tsx
@@ -1,40 +1,23 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import { EuiHorizontalRule, EuiPanel } from '@elastic/eui';
-import _ from 'lodash';
import moment from 'moment';
-import React, { Dispatch, SetStateAction, useMemo } from 'react';
-import { fixedIntervalToMilli, fixedIntervalToTickFormat, NoMatchMessage, PanelTitle } from '..';
-import { Plt } from './plt';
+import React, { useMemo } from 'react';
+import { Plt } from '../../../../visualizations/plotly/plot';
+import {
+ fixedIntervalToMilli,
+ fixedIntervalToTickFormat,
+ NoMatchMessage,
+ PanelTitle,
+} from '../helper_functions';
export function ErrorRatePlt(props: {
items: { items: Plotly.Data[]; fixedInterval: string };
- setStartTime: Dispatch
>;
- setEndTime: Dispatch>;
+ setStartTime: (startTime: string) => void;
+ setEndTime: (endTime: string) => void;
}) {
const getLayout = () =>
({
@@ -93,7 +76,7 @@ export function ErrorRatePlt(props: {
const layout = useMemo(() => getLayout(), [props.items]);
- const onClick = (event) => {
+ const onClick = (event: any) => {
if (!event?.points) return;
const point = event.points[0];
const start = point.data.x[point.pointNumber];
diff --git a/public/components/common/plots/latency_trend_plt.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/latency_trend_plt.tsx
similarity index 69%
rename from public/components/common/plots/latency_trend_plt.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/latency_trend_plt.tsx
index b283c11db..6589fe8d6 100644
--- a/public/components/common/plots/latency_trend_plt.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/latency_trend_plt.tsx
@@ -1,32 +1,11 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import _ from 'lodash';
import React, { useMemo } from 'react';
-import { Plt } from './plt';
+import { Plt } from '../../../../visualizations/plotly/plot';
export function LinePlt(props: { data: Plotly.Data[] }) {
const maxY = props.data[0]?.y ? Math.max(...props.data[0].y) : 0;
diff --git a/public/components/common/plots/service_map.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/service_map.tsx
similarity index 73%
rename from public/components/common/plots/service_map.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/service_map.tsx
index 6e545d4d1..a63604968 100644
--- a/public/components/common/plots/service_map.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/service_map.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
@@ -35,11 +14,16 @@ import {
EuiText,
} from '@elastic/eui';
import React, { useEffect, useState } from 'react';
+// @ts-ignore
import Graph from 'react-graph-vis';
-import _ from 'lodash';
-import { calculateTicks, getServiceMapGraph, NoMatchMessage, PanelTitle } from '..';
-import { ServiceMapScale } from './service_map_scale';
import { FilterType } from '../filters/filters';
+import {
+ calculateTicks,
+ getServiceMapGraph,
+ NoMatchMessage,
+ PanelTitle,
+} from '../helper_functions';
+import { ServiceMapScale } from './service_map_scale';
export interface ServiceObject {
[key: string]: {
@@ -51,6 +35,7 @@ export interface ServiceObject {
latency?: number;
error_rate?: number;
throughput?: number;
+ throughputPerMinute?: number;
relatedServices?: string[]; // services appear in the same traces this service appears
};
}
@@ -61,16 +46,26 @@ export function ServiceMap({
setIdSelected,
addFilter,
currService,
+ page,
}: {
serviceMap: ServiceObject;
- idSelected: string;
- setIdSelected: (newId: string) => void;
+ idSelected: 'latency' | 'error_rate' | 'throughput';
+ setIdSelected: (newId: 'latency' | 'error_rate' | 'throughput') => void;
addFilter?: (filter: FilterType) => void;
currService?: string;
+ page:
+ | 'app'
+ | 'appCreate'
+ | 'dashboard'
+ | 'traces'
+ | 'services'
+ | 'serviceView'
+ | 'detailFlyout'
+ | 'traceView';
}) {
const [invalid, setInvalid] = useState(false);
const [network, setNetwork] = useState(null);
- const [ticks, setTicks] = useState([]);
+ const [ticks, setTicks] = useState([]);
const [items, setItems] = useState({});
const [query, setQuery] = useState('');
const toggleButtons = [
@@ -123,10 +118,10 @@ export function ServiceMap({
};
const events = {
- select: (event) => {
+ select: (event: any) => {
const { nodes, edges } = event;
if (!addFilter || !nodes) return;
- const serviceName = items?.graph.nodes.find((node) => node.id === nodes[0])?.label;
+ const serviceName = items?.graph.nodes.find((node: any) => node.id === nodes[0])?.label;
if (serviceName) {
addFilter({
field: 'serviceName',
@@ -135,13 +130,15 @@ export function ServiceMap({
inverted: false,
disabled: false,
});
- window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
+ if (!['appCreate', 'detailFlyout'].includes(page)) {
+ window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
+ }
}
},
- hoverNode: (event) => {},
+ hoverNode: (event: any) => {},
};
- const onFocus = (service: string, networkInstance?) => {
+ const onFocus = (service: string, networkInstance?: any) => {
if (service.length === 0) {
setInvalid(false);
} else if (serviceMap[service]) {
@@ -156,8 +153,8 @@ export function ServiceMap({
useEffect(() => {
if (Object.keys(serviceMap).length === 0) return;
const values = Object.keys(serviceMap)
- .map((service) => serviceMap[service][idSelected] || null)
- .filter((val) => val !== null);
+ .filter((service) => serviceMap[service][idSelected])
+ .map((service) => serviceMap[service][idSelected]!);
const min = Math.min(...values);
const max = Math.max(...values);
const calculatedTicks = calculateTicks(min, max);
@@ -168,7 +165,7 @@ export function ServiceMap({
idSelected,
calculatedTicks,
currService,
- serviceMap[currService]?.relatedServices
+ serviceMap[currService!]?.relatedServices
)
);
}, [serviceMap, idSelected]);
@@ -176,12 +173,16 @@ export function ServiceMap({
return (
<>
-
+ {page === 'app' ? (
+
+ ) : (
+
+ )}
setIdSelected(id)}
+ onChange={(id) => setIdSelected(id as 'latency' | 'error_rate' | 'throughput')}
buttonSize="s"
color="text"
/>
@@ -210,7 +211,7 @@ export function ServiceMap({
graph={items.graph}
options={options}
events={events}
- getNetwork={(networkInstance) => {
+ getNetwork={(networkInstance: any) => {
setNetwork(networkInstance);
if (currService) onFocus(currService, networkInstance);
}}
diff --git a/public/components/common/plots/service_map_scale.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/service_map_scale.tsx
similarity index 78%
rename from public/components/common/plots/service_map_scale.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/service_map_scale.tsx
index 13dca52c7..86d11b7ec 100644
--- a/public/components/common/plots/service_map_scale.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/service_map_scale.tsx
@@ -1,39 +1,18 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText } from '@elastic/eui';
import _ from 'lodash';
import React, { useEffect, useState } from 'react';
-import { getServiceMapScaleColor } from '..';
+import { Plt } from '../../../../visualizations/plotly/plot';
import unmatchedNode from '../../../images/unmatched_node.png';
-import { Plt } from './plt';
+import { getServiceMapScaleColor } from '../helper_functions';
import { ServiceObject } from './service_map';
export function ServiceMapScale(props: {
- idSelected: string;
+ idSelected: 'latency' | 'error_rate' | 'throughput';
serviceMap: ServiceObject;
ticks: number[];
}) {
@@ -141,7 +120,7 @@ export function ServiceMapScale(props: {
/>
-
+
No match
diff --git a/public/components/common/plots/throughput_plt.tsx b/dashboards-observability/public/components/trace_analytics/components/common/plots/throughput_plt.tsx
similarity index 69%
rename from public/components/common/plots/throughput_plt.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/plots/throughput_plt.tsx
index 3c2ca2654..aba6bb283 100644
--- a/public/components/common/plots/throughput_plt.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/plots/throughput_plt.tsx
@@ -1,44 +1,23 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import { EuiHorizontalRule, EuiPanel } from '@elastic/eui';
import moment from 'moment';
-import React, { Dispatch, SetStateAction, useMemo } from 'react';
+import React, { useMemo } from 'react';
+import { Plt } from '../../../../visualizations/plotly/plot';
import {
fixedIntervalToMilli,
fixedIntervalToTickFormat,
NoMatchMessage,
PanelTitle,
-} from '..';
-import { Plt } from './plt';
+} from '../helper_functions';
export function ThroughputPlt(props: {
items: { items: Plotly.Data[]; fixedInterval: string };
- setStartTime: Dispatch>;
- setEndTime: Dispatch>;
+ setStartTime: (startTime: string) => void;
+ setEndTime: (endTime: string) => void;
}) {
const layout = useMemo(
() =>
diff --git a/public/components/common/search_bar.tsx b/dashboards-observability/public/components/trace_analytics/components/common/search_bar.tsx
similarity index 56%
rename from public/components/common/search_bar.tsx
rename to dashboards-observability/public/components/trace_analytics/components/common/search_bar.tsx
index 5b01484c4..b67b8864e 100644
--- a/public/components/common/search_bar.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/common/search_bar.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
@@ -33,14 +12,21 @@ import {
EuiSuperDatePicker,
} from '@elastic/eui';
import _ from 'lodash';
-import React, { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react';
-import { FiltersProps, Filters } from './filters/filters';
+import React, { useState } from 'react';
+import { uiSettingsService } from '../../../../../common/utils';
+import { Filters, FiltersProps } from './filters/filters';
-export const renderDatePicker = (startTime, setStartTime, endTime, setEndTime) => {
+export const renderDatePicker = (
+ startTime: string,
+ setStartTime: (startTime: string) => void,
+ endTime: string,
+ setEndTime: (endTime: string) => void
+) => {
return (
{
setStartTime(e.start);
@@ -52,16 +38,16 @@ export const renderDatePicker = (startTime, setStartTime, endTime, setEndTime) =
export interface SearchBarProps extends FiltersProps {
query: string;
- setQuery: Dispatch>;
+ setQuery: (query: string) => void;
startTime: string;
- setStartTime: Dispatch>;
+ setStartTime: (startTime: string) => void;
endTime: string;
- setEndTime: Dispatch>;
+ setEndTime: (endTime: string) => void;
}
interface SearchBarOwnProps extends SearchBarProps {
refresh: () => void;
- page: 'dashboard' | 'traces' | 'services';
+ page: 'dashboard' | 'traces' | 'services' | 'app';
datepickerOnly?: boolean;
}
@@ -89,13 +75,12 @@ export function SearchBar(props: SearchBarOwnProps) {
/>
)}
-
+
{renderDatePicker(props.startTime, props.setStartTime, props.endTime, props.setEndTime)}
@@ -107,7 +92,12 @@ export function SearchBar(props: SearchBarOwnProps) {
{!props.datepickerOnly && (
<>
-
+
>
)}
>
diff --git a/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap
new file mode 100644
index 000000000..be5cacf4a
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap
@@ -0,0 +1,3228 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Dashboard component renders dashboard 1`] = `
+
+
+
+ Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 5 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ + Add filter
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="m"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+ + Add filter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Latency by trace group
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ □
+
+ < 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ■
+
+ >= 95 percentile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Trace error rate over time
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Traces over time
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Dashboard component renders empty dashboard 1`] = `
+
+
+
+ Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 5 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ + Add filter
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="m"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+ + Add filter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Learn more
+
+ }
+ body={
+
+ The indices required for trace analytics (otel-v1-apm-span-* and otel-v1-apm-service-map*) do not exist or you do not have permission to access them.
+
+ }
+ title={
+
+ Trace Analytics not set up
+
+ }
+ >
+
+
+
+
+
+ Trace Analytics not set up
+
+
+
+
+
+
+
+
+
+ The indices required for trace analytics (otel-v1-apm-span-* and otel-v1-apm-service-map*) do not exist or you do not have permission to access them.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Learn more
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/public/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap
similarity index 99%
rename from public/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap
index 26f30e846..eca701df5 100644
--- a/public/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard_table.test.tsx.snap
@@ -31,6 +31,8 @@ exports[`Dashboard table component renders dashboard table 1`] = `
},
]
}
+ loading={false}
+ page="dashboard"
setRedirect={[MockFunction]}
>
@@ -391,6 +393,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
},
]
}
+ data-test-subj="dashboardTable"
items={
Array [
Object {
@@ -407,6 +410,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
},
]
}
+ loading={false}
onTableChange={[Function]}
pagination={
Object {
@@ -637,6 +641,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
},
]
}
+ data-test-subj="dashboardTable"
items={
Array [
Object {
@@ -653,6 +658,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
},
]
}
+ loading={false}
noItemsMessage="No items found"
onChange={[Function]}
pagination={
@@ -711,6 +717,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
>
@@ -2285,6 +2292,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
]
}
debug={false}
+ divId="explorerPlotComponent"
layout={
Object {
"autosize": true,
@@ -2337,6 +2345,7 @@ exports[`Dashboard table component renders dashboard table 1`] = `
useResizeHandler={true}
>
diff --git a/public/components/dashboard/__tests__/__snapshots__/latency_trend_cell.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/latency_trend_cell.test.tsx.snap
similarity index 100%
rename from public/components/dashboard/__tests__/__snapshots__/latency_trend_cell.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/latency_trend_cell.test.tsx.snap
diff --git a/public/components/dashboard/__tests__/dashboard.test.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx
similarity index 54%
rename from public/components/dashboard/__tests__/dashboard.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx
index dc59a20bc..0f5c16918 100644
--- a/public/components/dashboard/__tests__/dashboard.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx
@@ -1,59 +1,55 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
*/
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-import React from 'react';
-import { render } from '@testing-library/react';
-import { configure, mount, shallow } from 'enzyme';
+import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
import { Dashboard } from '..';
+import { CoreStart } from '../../../../../../../../src/core/public';
+import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks';
describe('Dashboard component', () => {
configure({ adapter: new Adapter() });
it('renders empty dashboard', () => {
- const http = jest.fn();
- const setBreadcrumbs = jest.fn();
+ const core = coreStartMock;
const setQuery = jest.fn();
const setFilters = jest.fn();
const setStartTime = jest.fn();
const setEndTime = jest.fn();
const wrapper = mount(
);
@@ -61,26 +57,42 @@ describe('Dashboard component', () => {
});
it('renders dashboard', () => {
- const http = jest.fn();
- const setBreadcrumbs = jest.fn();
+ const core = coreStartMock;
const setQuery = jest.fn();
const setFilters = jest.fn();
const setStartTime = jest.fn();
const setEndTime = jest.fn();
const wrapper = mount(
);
diff --git a/public/components/dashboard/__tests__/dashboard_table.test.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard_table.test.tsx
similarity index 66%
rename from public/components/dashboard/__tests__/dashboard_table.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard_table.test.tsx
index efb5855d3..58c569d45 100644
--- a/public/components/dashboard/__tests__/dashboard_table.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/dashboard_table.test.tsx
@@ -1,33 +1,11 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
*/
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-import React from 'react';
-import { render } from '@testing-library/react';
-import { configure, mount, shallow } from 'enzyme';
+import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
import { DashboardTable } from '../dashboard_table';
describe('Dashboard table component', () => {
@@ -44,6 +22,8 @@ describe('Dashboard table component', () => {
addFilter={addFilter}
addPercentileFilter={addPercentileFilter}
setRedirect={setRedirect}
+ loading={false}
+ page="dashboard"
/>
);
@@ -79,6 +59,8 @@ describe('Dashboard table component', () => {
addFilter={addFilter}
addPercentileFilter={addPercentileFilter}
setRedirect={setRedirect}
+ loading={false}
+ page="dashboard"
/>
);
@@ -87,7 +69,9 @@ describe('Dashboard table component', () => {
wrapper.find('button[data-test-subj="dashboard-table-percentile-button-1"]').simulate('click');
wrapper.find('button[data-test-subj="dashboard-table-percentile-button-2"]').simulate('click');
expect(addPercentileFilter).toBeCalledTimes(2);
- wrapper.find('button[data-test-subj="dashboard-table-trace-group-name-button"]').simulate('click');
+ wrapper
+ .find('button[data-test-subj="dashboard-table-trace-group-name-button"]')
+ .simulate('click');
expect(addFilter).toBeCalled();
wrapper.find('button[data-test-subj="dashboard-table-traces-button"]').simulate('click');
expect(setRedirect).toBeCalledWith(true);
diff --git a/public/components/dashboard/__tests__/latency_trend_cell.test.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/latency_trend_cell.test.tsx
similarity index 51%
rename from public/components/dashboard/__tests__/latency_trend_cell.test.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/latency_trend_cell.test.tsx
index d8231b44f..6b924d931 100644
--- a/public/components/dashboard/__tests__/latency_trend_cell.test.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/__tests__/latency_trend_cell.test.tsx
@@ -1,33 +1,11 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
*/
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-import React from 'react';
-import { render } from '@testing-library/react';
-import { configure, mount, shallow } from 'enzyme';
+import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
import { LatencyTrendCell } from '../latency_trend_cell';
describe('Latency trend cell component', () => {
@@ -40,7 +18,7 @@ describe('Latency trend cell component', () => {
const wrapper = mount( );
expect(wrapper).toMatchSnapshot();
- wrapper.find('button[aria-label="Open popover"]').simulate('click')
- wrapper.find('button[aria-label="Close popover"]').simulate('click')
+ wrapper.find('button[aria-label="Open popover"]').simulate('click');
+ wrapper.find('button[aria-label="Close popover"]').simulate('click');
});
});
diff --git a/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard.tsx
new file mode 100644
index 000000000..c5bf0a501
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard.tsx
@@ -0,0 +1,25 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiBreadcrumb, EuiTitle } from '@elastic/eui';
+import React from 'react';
+import { TraceAnalyticsComponentDeps } from '../../home';
+import { DashboardContent } from './dashboard_content';
+
+export interface DashboardProps extends TraceAnalyticsComponentDeps {
+ childBreadcrumbs: EuiBreadcrumb[];
+ page: 'dashboard' | 'app';
+}
+
+export function Dashboard(props: DashboardProps) {
+ return (
+ <>
+
+ Dashboard
+
+
+ >
+ );
+}
diff --git a/public/components/dashboard/dashboard.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_content.tsx
similarity index 53%
rename from public/components/dashboard/dashboard.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_content.tsx
index 7e5461527..64182d120 100644
--- a/public/components/dashboard/dashboard.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_content.tsx
@@ -1,31 +1,12 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
+/* eslint-disable react-hooks/exhaustive-deps */
import dateMath from '@elastic/datemath';
-import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
+import _ from 'lodash';
import React, { useEffect, useState } from 'react';
import {
handleDashboardErrorRatePltRequest,
@@ -33,48 +14,57 @@ import {
handleDashboardThroughputPltRequest,
} from '../../requests/dashboard_request_handler';
import { handleServiceMapRequest } from '../../requests/services_request_handler';
-import { CoreDeps } from '../app';
+import { FilterType } from '../common/filters/filters';
+import { getValidFilterFields } from '../common/filters/filter_helpers';
import {
filtersToDsl,
getPercentileFilter,
milliToNanoSec,
minFixedInterval,
MissingConfigurationMessage,
- SearchBar,
- SearchBarProps,
-} from '../common';
-import { FilterType } from '../common/filters/filters';
-import { getValidFilterFields } from '../common/filters/filter_helpers';
+} from '../common/helper_functions';
import { ErrorRatePlt } from '../common/plots/error_rate_plt';
import { ServiceMap, ServiceObject } from '../common/plots/service_map';
import { ThroughputPlt } from '../common/plots/throughput_plt';
+import { SearchBar } from '../common/search_bar';
+import { DashboardProps } from './dashboard';
import { DashboardTable } from './dashboard_table';
-interface DashboardProps extends SearchBarProps, CoreDeps {}
-
-export function Dashboard(props: DashboardProps) {
+export function DashboardContent(props: DashboardProps) {
+ const {
+ http,
+ chrome,
+ page,
+ query,
+ appConfigs,
+ startTime,
+ endTime,
+ childBreadcrumbs,
+ parentBreadcrumbs,
+ filters,
+ indicesExist,
+ setStartTime,
+ setEndTime,
+ setQuery,
+ setFilters,
+ } = props;
const [tableItems, setTableItems] = useState([]);
const [throughputPltItems, setThroughputPltItems] = useState({ items: [], fixedInterval: '1h' });
const [errorRatePltItems, setErrorRatePltItems] = useState({ items: [], fixedInterval: '1h' });
const [serviceMap, setServiceMap] = useState({});
- const [serviceMapIdSelected, setServiceMapIdSelected] = useState('latency');
+ const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
+ 'latency' | 'error_rate' | 'throughput'
+ >('latency');
const [percentileMap, setPercentileMap] = useState<{ [traceGroup: string]: number[] }>({});
+ const [filteredService, setFilteredService] = useState('');
const [redirect, setRedirect] = useState(true);
+ const [loading, setLoading] = useState(false);
useEffect(() => {
- props.setBreadcrumbs([
- {
- text: 'Trace Analytics',
- href: '#',
- },
- {
- text: 'Dashboard',
- href: '#/dashboard',
- },
- ]);
- const validFilters = getValidFilterFields('dashboard');
- props.setFilters([
- ...props.filters.map((filter) => ({
+ chrome.setBreadcrumbs([...parentBreadcrumbs, ...childBreadcrumbs]);
+ const validFilters = getValidFilterFields(page);
+ setFilters([
+ ...filters.map((filter) => ({
...filter,
locked: validFilters.indexOf(filter.field) === -1,
})),
@@ -83,71 +73,85 @@ export function Dashboard(props: DashboardProps) {
}, []);
useEffect(() => {
- if (!redirect && props.indicesExist) refresh();
- }, [props.filters, props.startTime, props.endTime]);
+ let newFilteredService = '';
+ for (const filter of filters) {
+ if (filter.field === 'serviceName') {
+ newFilteredService = filter.value;
+ break;
+ }
+ }
+ setFilteredService(newFilteredService);
+ if (!redirect && indicesExist) refresh(newFilteredService);
+ }, [filters, startTime, endTime, appConfigs]);
- const refresh = async () => {
- const DSL = filtersToDsl(props.filters, props.query, props.startTime, props.endTime);
- const timeFilterDSL = filtersToDsl([], '', props.startTime, props.endTime);
- const latencyTrendStartTime = dateMath
- .parse(props.endTime)
- ?.subtract(24, 'hours')
- .toISOString()!;
+ const refresh = async (currService?: string) => {
+ setLoading(true);
+ const DSL = filtersToDsl(filters, query, startTime, endTime, page, appConfigs);
+ const timeFilterDSL = filtersToDsl([], '', startTime, endTime, page, appConfigs);
+ const latencyTrendStartTime = dateMath.parse(endTime)?.subtract(24, 'hours').toISOString()!;
const latencyTrendDSL = filtersToDsl(
- props.filters,
- props.query,
+ filters,
+ query,
latencyTrendStartTime,
- props.endTime
+ endTime,
+ page,
+ appConfigs
);
- const fixedInterval = minFixedInterval(props.startTime, props.endTime);
+ const fixedInterval = minFixedInterval(startTime, endTime);
handleDashboardRequest(
- props.http,
+ http,
DSL,
timeFilterDSL,
latencyTrendDSL,
tableItems,
setTableItems,
setPercentileMap
- );
+ ).then(() => setLoading(false));
handleDashboardThroughputPltRequest(
- props.http,
+ http,
DSL,
fixedInterval,
throughputPltItems,
setThroughputPltItems
);
handleDashboardErrorRatePltRequest(
- props.http,
+ http,
DSL,
fixedInterval,
errorRatePltItems,
setErrorRatePltItems
);
- handleServiceMapRequest(props.http, DSL, serviceMap, setServiceMap);
+ // service map should not be filtered by service name (https://github.com/opensearch-project/observability/issues/442)
+ const serviceMapDSL = _.cloneDeep(DSL);
+ serviceMapDSL.query.bool.must = serviceMapDSL.query.bool.must.filter(
+ (must: any) => must?.term?.serviceName == null
+ );
+ handleServiceMapRequest(http, serviceMapDSL, setServiceMap, currService || filteredService);
};
const addFilter = (filter: FilterType) => {
- for (const addedFilter of props.filters) {
- if (
- addedFilter.field === filter.field &&
- addedFilter.operator === filter.operator &&
- addedFilter.value === filter.value
- ) {
+ for (let i = 0; i < filters.length; i++) {
+ const addedFilter = filters[i];
+ if (addedFilter.field === filter.field) {
+ if (addedFilter.operator === filter.operator && addedFilter.value === filter.value) return;
+ const newFilters = [...filters];
+ newFilters.splice(i, 1, filter);
+ setFilters(newFilters);
return;
}
}
- const newFilters = [...props.filters, filter];
- props.setFilters(newFilters);
+ const newFilters = [...filters, filter];
+ setFilters(newFilters);
};
- const addPercentileFilter = (condition = 'gte', additionalFilters = []) => {
+ const addPercentileFilter = (condition = 'gte', additionalFilters = [] as FilterType[]) => {
if (tableItems.length === 0 || Object.keys(percentileMap).length === 0) return;
- for (let i = 0; i < props.filters.length; i++) {
- if (props.filters[i].custom) {
- const newFilter = JSON.parse(JSON.stringify(props.filters[i]));
- newFilter.custom.query.bool.should.forEach((should) =>
- should.bool.must.forEach((must) => {
+ for (let i = 0; i < filters.length; i++) {
+ if (filters[i].custom) {
+ const newFilter = JSON.parse(JSON.stringify(filters[i]));
+ newFilter.custom.query.bool.should.forEach((should: any) =>
+ should.bool.must.forEach((must: any) => {
const range = must?.range?.['traceGroupFields.durationInNanos'];
if (range) {
const duration = range.lt || range.lte || range.gt || range.gte;
@@ -160,9 +164,9 @@ export function Dashboard(props: DashboardProps) {
})
);
newFilter.value = condition === 'gte' ? '>= 95th' : '< 95th';
- const newFilters = [...props.filters, ...additionalFilters];
+ const newFilters = [...filters, ...additionalFilters];
newFilters.splice(i, 1, newFilter);
- props.setFilters(newFilters);
+ setFilters(newFilters);
return;
}
}
@@ -175,36 +179,36 @@ export function Dashboard(props: DashboardProps) {
percentileMaps,
condition === 'gte' ? '>= 95th' : '< 95th'
);
- const newFilters = [...props.filters, percentileFilter, ...additionalFilters];
- props.setFilters(newFilters);
+ const newFilters = [...filters, percentileFilter, ...additionalFilters];
+ setFilters(newFilters);
};
return (
<>
-
- Dashboard
-
- {props.indicesExist ? (
+ {indicesExist ? (
<>
@@ -214,6 +218,8 @@ export function Dashboard(props: DashboardProps) {
serviceMap={serviceMap}
idSelected={serviceMapIdSelected}
setIdSelected={setServiceMapIdSelected}
+ currService={filteredService}
+ page={page}
/>
@@ -221,15 +227,15 @@ export function Dashboard(props: DashboardProps) {
diff --git a/public/components/dashboard/dashboard_table.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_table.tsx
similarity index 90%
rename from public/components/dashboard/dashboard_table.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_table.tsx
index 949a306ef..cba174088 100644
--- a/public/components/dashboard/dashboard_table.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/dashboard_table.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import {
@@ -39,10 +18,11 @@ import {
EuiToolTip,
PropertySort,
} from '@elastic/eui';
+import { CriteriaWithPagination } from '@elastic/eui/src/components/basic_table/basic_table';
import _ from 'lodash';
import React, { useMemo, useState } from 'react';
-import { calculateTicks, NoMatchMessage, PanelTitle } from '../common';
import { FilterType } from '../common/filters/filters';
+import { calculateTicks, NoMatchMessage, PanelTitle } from '../common/helper_functions';
import { BoxPlt } from '../common/plots/box_plt';
import { LatencyTrendCell } from './latency_trend_cell';
@@ -52,8 +32,10 @@ export function DashboardTable(props: {
addFilter: (filter: FilterType) => void;
addPercentileFilter: (condition?: 'gte' | 'lte', additionalFilters?: FilterType[]) => void;
setRedirect: (redirect: boolean) => void;
+ loading: boolean;
+ page: 'dashboard' | 'traces' | 'services' | 'app';
}) {
- const getVarianceProps = (items) => {
+ const getVarianceProps = (items: any[]) => {
if (items.length === 0) {
return { minRange: 0, maxRange: 0, ticks: [0, 0], scale: '' };
}
@@ -130,7 +112,11 @@ export function DashboardTable(props: {
})
}
>
- {item.length < 48 ? item : {_.truncate(item, { length: 48 })}
}
+ {item.length < 48 ? (
+ decodeURI(item)
+ ) : (
+ {_.truncate(decodeURI(item), { length: 48 })}
+ )}
) : (
'-'
@@ -176,7 +162,7 @@ export function DashboardTable(props: {
);
const currPercentileFilter = filter ? filter.value : '';
return item ? (
- // expand plot ranges to accomondate scale
+ // expand plot ranges to accommodate scale
{
- props.setRedirect(true);
props.addFilter({
field: 'traceGroup',
operator: 'is',
@@ -348,7 +333,10 @@ export function DashboardTable(props: {
inverted: false,
disabled: false,
});
- location.assign('#/traces');
+ if (props.page !== 'app') {
+ props.setRedirect(true);
+ location.assign('#/trace_analytics/traces');
+ }
}}
>
@@ -357,7 +345,7 @@ export function DashboardTable(props: {
},
] as Array>;
- const renderTitleBar = (totalItems) => {
+ const renderTitleBar = (totalItems: number) => {
return (
@@ -390,7 +378,7 @@ export function DashboardTable(props: {
};
const varianceProps = useMemo(() => getVarianceProps(props.items), [props.items]);
- const columns = useMemo(() => getColumns(), [props.items]);
+ const columns = useMemo(() => getColumns(), [props.items, props.filters]);
const titleBar = useMemo(() => renderTitleBar(props.items?.length), [props.items]);
const [sorting, setSorting] = useState<{ sort: PropertySort }>({
@@ -400,9 +388,9 @@ export function DashboardTable(props: {
},
});
- const onTableChange = async ({ page, sort }) => {
+ const onTableChange = async ({ page, sort }: CriteriaWithPagination) => {
if (typeof sort?.field !== 'string') return;
- setSorting({ sort });
+ setSorting({ sort } as { sort: PropertySort });
};
return (
@@ -413,6 +401,7 @@ export function DashboardTable(props: {
{props.items?.length > 0 ? (
) : (
diff --git a/dashboards-observability/public/components/trace_analytics/components/dashboard/index.ts b/dashboards-observability/public/components/trace_analytics/components/dashboard/index.ts
new file mode 100644
index 000000000..346331a32
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/index.ts
@@ -0,0 +1,6 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { Dashboard } from './dashboard';
diff --git a/public/components/dashboard/latency_trend_cell.tsx b/dashboards-observability/public/components/trace_analytics/components/dashboard/latency_trend_cell.tsx
similarity index 66%
rename from public/components/dashboard/latency_trend_cell.tsx
rename to dashboards-observability/public/components/trace_analytics/components/dashboard/latency_trend_cell.tsx
index ebd9e5d17..2422c4d18 100644
--- a/public/components/dashboard/latency_trend_cell.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/dashboard/latency_trend_cell.tsx
@@ -1,27 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPopover, EuiText } from '@elastic/eui';
diff --git a/public/components/services/__tests__/__snapshots__/service_view.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap
similarity index 99%
rename from public/components/services/__tests__/__snapshots__/service_view.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap
index 7c2fc4439..40b856fb8 100644
--- a/public/components/services/__tests__/__snapshots__/service_view.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap
@@ -67,7 +67,7 @@ exports[`Service view component renders service view 1`] = `
},
]
}
- dateFormat="MMM D, YYYY @ HH:mm:ss.SSS"
+ dateFormat=""
end="now"
isAutoRefreshOnly={false}
isDisabled={false}
@@ -219,6 +219,7 @@ exports[`Service view component renders service view 1`] = `
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services.test.tsx.snap
new file mode 100644
index 000000000..f52278b5f
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services.test.tsx.snap
@@ -0,0 +1,3458 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Services component renders empty services page 1`] = `
+
+
+
+ Services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 5 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ + Add filter
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="m"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+ + Add filter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Learn more
+
+ }
+ body={
+
+ The indices required for trace analytics (otel-v1-apm-span-* and otel-v1-apm-service-map*) do not exist or you do not have permission to access them.
+
+ }
+ title={
+
+ Trace Analytics not set up
+
+ }
+ >
+
+
+
+
+
+ Trace Analytics not set up
+
+
+
+
+
+
+
+
+
+ The indices required for trace analytics (otel-v1-apm-span-* and otel-v1-apm-service-map*) do not exist or you do not have permission to access them.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Learn more
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`Services component renders services page 1`] = `
+
+
+
+ Services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="QuickSelectPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="m"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
}
+ iconType={false}
+ isCustom={true}
+ startDateControl={
}
+ >
+
+
+ Last 5 minutes
+
+
+ Show dates
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Refresh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="none"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+
+
+
+ + Add filter
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ isOpen={false}
+ ownFocus={false}
+ panelPaddingSize="m"
+ withTitle={true}
+ >
+
+
+
+
+
+
+
+
+ + Add filter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Services
+
+
+ (0)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Service map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+ }
+ title={
+
+ No matches
+
+ }
+ >
+
+
+
+
+
+ No matches
+
+
+
+
+
+
+
+
+
+ No data matches the selected filter. Clear the filter and/or increase the time range to see more results.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/public/components/services/__tests__/__snapshots__/services_table.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap
similarity index 99%
rename from public/components/services/__tests__/__snapshots__/services_table.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap
index 654630d5a..3fc805b3e 100644
--- a/public/components/services/__tests__/__snapshots__/services_table.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/__snapshots__/services_table.test.tsx.snap
@@ -5,10 +5,10 @@ exports[`Services table component renders empty services table message 1`] = `
addFilter={[MockFunction]}
indicesExist={true}
items={Array []}
- refresh={[MockFunction]}
- serviceQuery="test"
+ loading={false}
+ nameColumnAction={[Function]}
setRedirect={[MockFunction]}
- setServiceQuery={[MockFunction]}
+ traceColumnAction={[Function]}
>
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/__tests__/service_view.test.tsx b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/service_view.test.tsx
new file mode 100644
index 000000000..b48055548
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/service_view.test.tsx
@@ -0,0 +1,44 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, shallow } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { ServiceView } from '..';
+import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks';
+
+describe('Service view component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders service view', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const addFilter = jest.fn();
+ const wrapper = shallow(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services.test.tsx b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services.test.tsx
new file mode 100644
index 000000000..fca7a6c44
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services.test.tsx
@@ -0,0 +1,102 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import React from 'react';
+import { Services } from '..';
+import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks';
+
+describe('Services component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty services page', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const serviceBreadcrumbs = [
+ {
+ text: 'Trace analytics',
+ href: '#/trace_analytics/home',
+ },
+ {
+ text: 'Services',
+ href: '#/trace_analytics/services',
+ },
+ ];
+ const nameColumnAction = (item: any) =>
+ location.assign(`#/trace_analytics/services/${encodeURIComponent(item)}`);
+ const traceColumnAction = () => location.assign('#/trace_analytics/traces');
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders services page', () => {
+ const core = coreStartMock;
+ const setQuery = jest.fn();
+ const setFilters = jest.fn();
+ const setStartTime = jest.fn();
+ const setEndTime = jest.fn();
+ const serviceBreadcrumbs = [
+ {
+ text: 'Trace analytics',
+ href: '#/trace_analytics/home',
+ },
+ {
+ text: 'Services',
+ href: '#/trace_analytics/services',
+ },
+ ];
+ const nameColumnAction = (item: any) =>
+ location.assign(`#/trace_analytics/services/${encodeURIComponent(item)}`);
+ const traceColumnAction = () => location.assign('#/trace_analytics/traces');
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services_table.test.tsx b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services_table.test.tsx
new file mode 100644
index 000000000..a4eb24e3c
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/__tests__/services_table.test.tsx
@@ -0,0 +1,66 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { configure, mount } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import { ServicesTable } from '../services_table';
+
+describe('Services table component', () => {
+ configure({ adapter: new Adapter() });
+
+ it('renders empty services table message', () => {
+ const addFilter = jest.fn();
+ const setRedirect = jest.fn();
+ const nameColumnAction = (item: any) =>
+ location.assign(`#/trace_analytics/services/${encodeURIComponent(item)}`);
+ const traceColumnAction = () => location.assign('#/trace_analytics/traces');
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('renders services table', () => {
+ const tableItems = [
+ {
+ name: 'database',
+ average_latency: 49.54,
+ error_rate: 3.77,
+ throughput: 53,
+ traces: 31,
+ connected_services: ['order', 'inventory'],
+ number_of_connected_services: 2,
+ },
+ ];
+ const addFilter = jest.fn();
+ const setRedirect = jest.fn();
+ const nameColumnAction = (item: any) =>
+ location.assign(`#/trace_analytics/services/${encodeURIComponent(item)}`);
+ const traceColumnAction = () => location.assign('#/trace_analytics/traces');
+ const wrapper = mount(
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/index.ts b/dashboards-observability/public/components/trace_analytics/components/services/index.ts
new file mode 100644
index 000000000..d38e5a4a3
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { Services } from './services';
+export { ServiceView } from './service_view';
+export { ServiceMap } from '../common/plots/service_map';
diff --git a/public/components/services/service_view.tsx b/dashboards-observability/public/components/trace_analytics/components/services/service_view.tsx
similarity index 86%
rename from public/components/services/service_view.tsx
rename to dashboards-observability/public/components/trace_analytics/components/services/service_view.tsx
index a563eb348..555446ac2 100644
--- a/public/components/services/service_view.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/services/service_view.tsx
@@ -1,28 +1,8 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
+/* eslint-disable react-hooks/exhaustive-deps */
import {
EuiBadge,
@@ -40,18 +20,19 @@ import {
} from '@elastic/eui';
import _ from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
+import { TraceAnalyticsComponentDeps } from '../../home';
import {
handleServiceMapRequest,
handleServiceViewRequest,
} from '../../requests/services_request_handler';
-import { CoreDeps } from '../app';
-import { filtersToDsl, PanelTitle, renderDatePicker, SearchBarProps } from '../common';
import { FilterType } from '../common/filters/filters';
+import { filtersToDsl, PanelTitle } from '../common/helper_functions';
import { ServiceMap, ServiceObject } from '../common/plots/service_map';
+import { renderDatePicker, SearchBarProps } from '../common/search_bar';
import { SpanDetailFlyout } from '../traces/span_detail_flyout';
import { SpanDetailTable } from '../traces/span_detail_table';
-interface ServiceViewProps extends SearchBarProps, CoreDeps {
+interface ServiceViewProps extends TraceAnalyticsComponentDeps {
serviceName: string;
addFilter: (filter: FilterType) => void;
}
@@ -59,36 +40,39 @@ interface ServiceViewProps extends SearchBarProps, CoreDeps {
export function ServiceView(props: ServiceViewProps) {
const [fields, setFields] = useState({});
const [serviceMap, setServiceMap] = useState({});
- const [serviceMapIdSelected, setServiceMapIdSelected] = useState('latency');
+ const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
+ 'latency' | 'error_rate' | 'throughput'
+ >('latency');
const [redirect, setRedirect] = useState(false);
+ const refresh = () => {
+ const DSL = filtersToDsl(props.filters, props.query, props.startTime, props.endTime);
+ handleServiceViewRequest(props.serviceName, props.http, DSL, setFields);
+ handleServiceMapRequest(props.http, DSL, setServiceMap, props.serviceName);
+ };
+
useEffect(() => {
- props.setBreadcrumbs([
+ props.chrome.setBreadcrumbs([
+ ...props.parentBreadcrumbs,
{
- text: 'Trace Analytics',
- href: '#',
+ text: 'Trace analytics',
+ href: '#/trace_analytics/home',
},
{
text: 'Services',
- href: '#/services',
+ href: '#/trace_analytics/services',
},
{
text: props.serviceName,
- href: `#/services/${encodeURIComponent(props.serviceName)}`,
+ href: `#/trace_analytics/services/${encodeURIComponent(props.serviceName)}`,
},
]);
- }, []);
+ }, [props.serviceName]);
useEffect(() => {
if (!redirect) refresh();
}, [props.startTime, props.endTime, props.serviceName]);
- const refresh = () => {
- const DSL = filtersToDsl(props.filters, props.query, props.startTime, props.endTime);
- handleServiceViewRequest(props.serviceName, props.http, DSL, fields, setFields);
- handleServiceMapRequest(props.http, DSL, serviceMap, setServiceMap, props.serviceName);
- };
-
const renderTitle = (
serviceName: string,
startTime: SearchBarProps['startTime'],
@@ -140,7 +124,7 @@ export function ServiceView(props: ServiceViewProps) {
{fields.connected_services
? fields.connected_services
.map((service: string) => (
-
+
{service}
))
@@ -184,6 +168,7 @@ export function ServiceView(props: ServiceViewProps) {
{fields.traces === 0 || fields.traces ? (
{
+ setRedirect(true);
props.addFilter({
field: 'serviceName',
operator: 'is',
@@ -191,7 +176,7 @@ export function ServiceView(props: ServiceViewProps) {
inverted: false,
disabled: false,
});
- location.assign('#/traces');
+ location.assign('#/trace_analytics/traces');
}}
>
@@ -242,22 +227,22 @@ export function ServiceView(props: ServiceViewProps) {
};
useEffect(() => {
- const DSL = filtersToDsl(props.filters, props.query, props.startTime, props.endTime);
- DSL.query.bool.must.push({
+ const spanDSL = filtersToDsl(props.filters, props.query, props.startTime, props.endTime);
+ spanDSL.query.bool.must.push({
term: {
serviceName: props.serviceName,
},
});
spanFilters.map(({ field, value }) => {
if (value != null) {
- DSL.query.bool.must.push({
+ spanDSL.query.bool.must.push({
term: {
[field]: value,
},
});
}
});
- setDSL(DSL);
+ setDSL(spanDSL);
}, [props.startTime, props.endTime, props.serviceName, spanFilters]);
const addSpanFilter = (field: string, value: any) => {
@@ -329,6 +314,7 @@ export function ServiceView(props: ServiceViewProps) {
idSelected={serviceMapIdSelected}
setIdSelected={setServiceMapIdSelected}
currService={props.serviceName}
+ page="serviceView"
/>
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/services.tsx b/dashboards-observability/public/components/trace_analytics/components/services/services.tsx
new file mode 100644
index 000000000..04c6bad2f
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/services.tsx
@@ -0,0 +1,28 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { EuiBreadcrumb, EuiTitle } from '@elastic/eui';
+import _ from 'lodash';
+import React from 'react';
+import { TraceAnalyticsComponentDeps } from '../../home';
+import { ServicesContent } from './services_content';
+
+export interface ServicesProps extends TraceAnalyticsComponentDeps {
+ childBreadcrumbs: EuiBreadcrumb[];
+ nameColumnAction: any;
+ traceColumnAction: any;
+ page: 'services' | 'app';
+}
+
+export function Services(props: ServicesProps) {
+ return (
+ <>
+
+ Services
+
+
+ >
+ );
+}
diff --git a/dashboards-observability/public/components/trace_analytics/components/services/services_content.tsx b/dashboards-observability/public/components/trace_analytics/components/services/services_content.tsx
new file mode 100644
index 000000000..e4fa97e25
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/services/services_content.tsx
@@ -0,0 +1,141 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+/* eslint-disable react-hooks/exhaustive-deps */
+
+import { EuiSpacer } from '@elastic/eui';
+import _ from 'lodash';
+import React, { useEffect, useState } from 'react';
+import {
+ handleServiceMapRequest,
+ handleServicesRequest,
+} from '../../requests/services_request_handler';
+import { FilterType } from '../common/filters/filters';
+import { getValidFilterFields } from '../common/filters/filter_helpers';
+import { filtersToDsl } from '../common/helper_functions';
+import { ServiceMap, ServiceObject } from '../common/plots/service_map';
+import { SearchBar } from '../common/search_bar';
+import { ServicesProps } from './services';
+import { ServicesTable } from './services_table';
+
+export function ServicesContent(props: ServicesProps) {
+ const {
+ page,
+ http,
+ chrome,
+ filters,
+ query,
+ startTime,
+ endTime,
+ indicesExist,
+ appConfigs = [],
+ childBreadcrumbs,
+ parentBreadcrumbs,
+ nameColumnAction,
+ traceColumnAction,
+ setFilters,
+ setQuery,
+ setStartTime,
+ setEndTime,
+ } = props;
+ const [tableItems, setTableItems] = useState([]);
+ const [serviceMap, setServiceMap] = useState({});
+ const [serviceMapIdSelected, setServiceMapIdSelected] = useState<
+ 'latency' | 'error_rate' | 'throughput'
+ >('latency');
+ const [redirect, setRedirect] = useState(true);
+ const [loading, setLoading] = useState(false);
+ const [filteredService, setFilteredService] = useState('');
+
+ useEffect(() => {
+ chrome.setBreadcrumbs([...parentBreadcrumbs, ...childBreadcrumbs]);
+ const validFilters = getValidFilterFields('services');
+ setFilters([
+ ...filters.map((filter) => ({
+ ...filter,
+ locked: validFilters.indexOf(filter.field) === -1,
+ })),
+ ]);
+ setRedirect(false);
+ }, []);
+
+ useEffect(() => {
+ let newFilteredService = '';
+ for (const filter of filters) {
+ if (filter.field === 'serviceName') {
+ newFilteredService = filter.value;
+ break;
+ }
+ }
+ setFilteredService(newFilteredService);
+ if (!redirect && indicesExist) refresh(newFilteredService);
+ }, [filters, appConfigs]);
+
+ const refresh = async (currService?: string) => {
+ setLoading(true);
+ const DSL = filtersToDsl(filters, query, startTime, endTime, page, appConfigs);
+ // service map should not be filtered by service name
+ const serviceMapDSL = _.cloneDeep(DSL);
+ serviceMapDSL.query.bool.must = serviceMapDSL.query.bool.must.filter(
+ (must: any) => must?.term?.serviceName == null
+ );
+ await Promise.all([
+ handleServicesRequest(http, DSL, setTableItems),
+ handleServiceMapRequest(http, serviceMapDSL, setServiceMap, currService || filteredService),
+ ]);
+ setLoading(false);
+ };
+
+ const addFilter = (filter: FilterType) => {
+ for (let i = 0; i < filters.length; i++) {
+ const addedFilter = filters[i];
+ if (addedFilter.field === filter.field) {
+ if (addedFilter.operator === filter.operator && addedFilter.value === filter.value) return;
+ const newFilters = [...filters];
+ newFilters.splice(i, 1, filter);
+ setFilters(newFilters);
+ return;
+ }
+ }
+ const newFilters = [...filters, filter];
+ setFilters(newFilters);
+ };
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/public/components/services/services_table.tsx b/dashboards-observability/public/components/trace_analytics/components/services/services_table.tsx
similarity index 63%
rename from public/components/services/services_table.tsx
rename to dashboards-observability/public/components/trace_analytics/components/services/services_table.tsx
index 2cd43f8d4..d294f13ef 100644
--- a/public/components/services/services_table.tsx
+++ b/dashboards-observability/public/components/trace_analytics/components/services/services_table.tsx
@@ -1,28 +1,8 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
*/
+/* eslint-disable react-hooks/exhaustive-deps */
import {
EuiFlexGroup,
@@ -38,18 +18,33 @@ import {
} from '@elastic/eui';
import _ from 'lodash';
import React, { useMemo } from 'react';
-import { MissingConfigurationMessage, NoMatchMessage, PanelTitle } from '../common';
import { FilterType } from '../common/filters/filters';
+import {
+ MissingConfigurationMessage,
+ NoMatchMessage,
+ PanelTitle,
+} from '../common/helper_functions';
-export function ServicesTable(props: {
+interface ServicesTableProps {
items: any[];
+ indicesExist: boolean;
+ loading: boolean;
+ nameColumnAction: (item: any) => any;
+ traceColumnAction: any;
addFilter: (filter: FilterType) => void;
setRedirect: (redirect: boolean) => void;
- serviceQuery: string;
- setServiceQuery: (query: string) => void;
- refresh: () => void;
- indicesExist: boolean;
-}) {
+}
+
+export function ServicesTable(props: ServicesTableProps) {
+ const {
+ items,
+ indicesExist,
+ loading,
+ nameColumnAction,
+ traceColumnAction,
+ addFilter,
+ setRedirect,
+ } = props;
const renderTitleBar = (totalItems?: number) => {
return (
@@ -68,8 +63,8 @@ export function ServicesTable(props: {
name: 'Name',
align: 'left',
sortable: true,
- render: (item) => (
-
+ render: (item: any) => (
+ nameColumnAction(item)}>
{item.length < 24 ? item : {_.truncate(item, { length: 24 })}
}
),
@@ -79,7 +74,7 @@ export function ServicesTable(props: {
name: 'Average latency (ms)',
align: 'right',
sortable: true,
- render: (item) => (item === 0 || item ? _.round(item, 2) : '-'),
+ render: (item: any) => (item === 0 || item ? _.round(item, 2) : '-'),
},
{
field: 'error_rate',
@@ -95,7 +90,7 @@ export function ServicesTable(props: {
align: 'right',
sortable: true,
truncateText: true,
- render: (item) => (item === 0 || item ? : '-'),
+ render: (item: any) => (item === 0 || item ? : '-'),
},
{
field: 'number_of_connected_services',
@@ -104,7 +99,7 @@ export function ServicesTable(props: {
sortable: true,
truncateText: true,
width: '80px',
- render: (item) => (item === 0 || item ? item : '-'),
+ render: (item: any) => (item === 0 || item ? item : '-'),
},
{
field: 'connected_services',
@@ -112,12 +107,8 @@ export function ServicesTable(props: {
align: 'left',
sortable: true,
truncateText: true,
- render: (items) =>
- items ? (
- {_.truncate(items.join(', '), { length: 50 })}
- ) : (
- '-'
- ),
+ render: (item: any) =>
+ item ? {_.truncate(item.join(', '), { length: 50 })} : '-',
},
{
field: 'traces',
@@ -125,20 +116,20 @@ export function ServicesTable(props: {
align: 'right',
sortable: true,
truncateText: true,
- render: (item, row) => (
+ render: (item: any, row: any) => (
<>
{item === 0 || item ? (
{
- props.setRedirect(true);
- props.addFilter({
+ setRedirect(true);
+ addFilter({
field: 'serviceName',
operator: 'is',
value: row.name,
inverted: false,
disabled: false,
});
- location.assign('#/traces');
+ traceColumnAction();
}}
>
@@ -150,10 +141,10 @@ export function ServicesTable(props: {
),
},
] as Array>,
- [props.items]
+ [items]
);
- const titleBar = useMemo(() => renderTitleBar(props.items?.length), [props.items]);
+ const titleBar = useMemo(() => renderTitleBar(items?.length), [items]);
return (
<>
@@ -161,10 +152,10 @@ export function ServicesTable(props: {
{titleBar}
- {props.items?.length > 0 ? (
+ {items?.length > 0 ? (
- ) : props.indicesExist ? (
+ ) : indicesExist ? (
) : (
diff --git a/public/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap
similarity index 96%
rename from public/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap
index 38f14fa31..00b1ddc11 100644
--- a/public/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/flyout_list_item.test.tsx.snap
@@ -4,6 +4,7 @@ exports[` spec renders the component 1`] = `
spec renders the component with data 1`] = `
>
@@ -75,6 +76,7 @@ exports[`
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the component with data 1`] = `
spec renders the empty component 1`] = `
spanId="test"
>
@@ -1160,6 +1182,7 @@ exports[` spec renders the empty component 1`] = `
>
@@ -1234,6 +1257,7 @@ exports[`
spec renders the empty component 1`] = `
>
@@ -1308,6 +1332,7 @@ exports[`
spec renders the empty component 1`] = `
>
@@ -1370,6 +1395,7 @@ exports[`
spec renders the empty component 1`] = `
>
@@ -1447,6 +1473,7 @@ exports[`
spec renders the empty component 1`] = `
>
@@ -1615,6 +1642,7 @@ exports[`
spec renders the empty component 2`] = `
spanId="test"
>
@@ -1737,6 +1765,7 @@ exports[` spec renders the empty component 2`] = `
>
@@ -1811,6 +1840,7 @@ exports[`
spec renders the empty component 2`] = `
>
@@ -1885,6 +1915,7 @@ exports[`
spec renders the empty component 2`] = `
>
@@ -1947,6 +1978,7 @@ exports[`
spec renders the empty component 2`] = `
>
@@ -2024,6 +2056,7 @@ exports[`
spec renders the empty component 2`] = `
>
diff --git a/public/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap
similarity index 80%
rename from public/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap
rename to dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap
index bd546d11c..89378df5f 100644
--- a/public/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap
+++ b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/span_detail_panel.test.tsx.snap
@@ -60,6 +60,7 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
],
}
}
+ setData={[MockFunction]}
>
@@ -327,10 +328,53 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
}
>
HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
+ },
+ Object {
+ "hovertemplate": "%{x} ",
+ "marker": Object {
+ "color": "#7492e7",
+ },
+ "orientation": "h",
+ "text": Array [
+ "Error",
+ ],
+ "textfont": Object {
+ "color": Array [
+ "#c14125",
+ ],
+ },
+ "textposition": "outside",
+ "type": "bar",
+ "width": 0.4,
+ "x": Array [
+ 19.91,
+ ],
+ "y": Array [
+ "inventory HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
+ },
+ ]
+ }
layout={
Object {
- "height": 60,
+ "height": 110,
"margin": Object {
"b": 30,
"l": 260,
@@ -342,7 +386,7 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
"color": "#91989c",
"range": Array [
0,
- 0,
+ 23.892,
],
"showline": true,
"side": "top",
@@ -350,8 +394,12 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
},
"yaxis": Object {
"showgrid": false,
- "ticktext": Array [],
- "tickvals": Array [],
+ "ticktext": Array [
+ "inventory HTTP GET ",
+ ],
+ "tickvals": Array [
+ "inventory HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
},
}
}
@@ -365,13 +413,57 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
"displayModeBar": false,
}
}
- data={Array []}
+ data={
+ Array [
+ Object {
+ "hoverinfo": "none",
+ "marker": Object {
+ "color": "rgba(0, 0, 0, 0)",
+ },
+ "orientation": "h",
+ "showlegend": false,
+ "type": "bar",
+ "width": 0.4,
+ "x": Array [
+ 0,
+ ],
+ "y": Array [
+ "inventory HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
+ },
+ Object {
+ "hovertemplate": "%{x} ",
+ "marker": Object {
+ "color": "#7492e7",
+ },
+ "orientation": "h",
+ "text": Array [
+ "Error",
+ ],
+ "textfont": Object {
+ "color": Array [
+ "#c14125",
+ ],
+ },
+ "textposition": "outside",
+ "type": "bar",
+ "width": 0.4,
+ "x": Array [
+ 19.91,
+ ],
+ "y": Array [
+ "inventory HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
+ },
+ ]
+ }
debug={false}
+ divId="explorerPlotComponent"
layout={
Object {
"autosize": true,
"barmode": "stack",
- "height": 60,
+ "height": 110,
"hovermode": "closest",
"legend": Object {
"orientation": "h",
@@ -389,7 +481,7 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
"color": "#91989c",
"range": Array [
0,
- 0,
+ 23.892,
],
"showline": true,
"side": "top",
@@ -397,8 +489,12 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
},
"yaxis": Object {
"showgrid": false,
- "ticktext": Array [],
- "tickvals": Array [],
+ "ticktext": Array [
+ "inventory HTTP GET ",
+ ],
+ "tickvals": Array [
+ "inventory HTTP GET 4dec6080-61af-11eb-aee3-ef2f84ffa4a2",
+ ],
},
}
}
@@ -414,6 +510,7 @@ exports[`Service breakdown panel component renders service breakdown panel 1`] =
useResizeHandler={true}
>
@@ -148,6 +156,13 @@ exports[`Trace view component renders trace view 1`] = `
margin="m"
/>
+
+
diff --git a/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap
new file mode 100644
index 000000000..e0af247d6
--- /dev/null
+++ b/dashboards-observability/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap
@@ -0,0 +1,2374 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Traces component renders empty traces page 1`] = `
+
+
+
+ Traces
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+