From 3dd8269907b58a45c7c1f1f0e1384e9aced9da3c Mon Sep 17 00:00:00 2001 From: "alex.stanfield" <13949480+chaptersix@users.noreply.github.com> Date: Tue, 16 Dec 2025 14:31:34 -0600 Subject: [PATCH 1/3] port compose from docker-compose repo --- .github/actionlint-matcher.json | 17 + .github/workflows/compose.yaml | 173 + .github/workflows/extensibility.yaml | 10 +- .../promql-to-dd-go_build-publish.yaml | 10 +- .github/workflows/promql-to-dd-go_test.yaml | 10 +- .github/workflows/promql-to-scrape.yaml | 10 +- README.md | 5 +- compose/.env | 12 + compose/.pki/ca.pem | 18 + compose/README.md | 180 + compose/deployment/grafana/Dockerfile | 4 + compose/deployment/grafana/config.ini | 8 + .../grafana/dashboards/dockermetrics.json | 1019 +++++ .../grafana/dashboards/postgres.json | 3153 ++++++++++++++ .../deployment/grafana/dashboards/sdk.json | 2025 +++++++++ .../grafana/dashboards/temporal.json | 3631 +++++++++++++++++ .../grafana/provisioning/dashboards/all.yml | 6 + .../grafana/provisioning/datasources/all.yml | 16 + compose/deployment/loki/local-config.yaml | 57 + compose/deployment/nginx/nginx.conf | 95 + compose/deployment/otel/otel-config.yaml | 30 + compose/deployment/prometheus/config.yml | 41 + compose/docker-compose-cass-es.yml | 123 + compose/docker-compose-multirole.yaml | 400 ++ compose/docker-compose-mysql-es.yml | 134 + compose/docker-compose-mysql.yml | 102 + .../docker-compose-postgres-opensearch.yml | 141 + compose/docker-compose-postgres.yml | 103 + compose/docker-compose-tls.yml | 202 + compose/docker-compose-validate-multirole.yml | 23 + compose/docker-compose-validate.yml | 23 + compose/docker-compose.yml | 135 + compose/dynamicconfig/README.md | 39 + compose/dynamicconfig/development-cass.yaml | 3 + compose/dynamicconfig/development-sql.yaml | 6 + compose/dynamicconfig/docker.yaml | 0 compose/scripts/create-namespace.sh | 27 + compose/scripts/setup-cassandra-es.sh | 60 + compose/scripts/setup-mysql-es.sh | 54 + compose/scripts/setup-mysql.sh | 19 + compose/scripts/setup-postgres-es-tls.sh | 57 + compose/scripts/setup-postgres-es.sh | 54 + compose/scripts/setup-postgres-opensearch.sh | 54 + compose/scripts/setup-postgres.sh | 19 + compose/scripts/validate-temporal.sh | 95 + compose/tls/Dockerfile.admin-tools-tls | 9 + compose/tls/Dockerfile.auto-setup-tls | 9 + compose/tls/Dockerfile.tls | 24 + compose/tls/README.md | 28 + compose/tls/run-tls.sh | 16 + tls/tls-full/docker-compose.yml | 2 - tls/tls-simple/docker-compose.yml | 2 - 52 files changed, 12471 insertions(+), 22 deletions(-) create mode 100644 .github/actionlint-matcher.json create mode 100644 .github/workflows/compose.yaml create mode 100644 compose/.env create mode 100644 compose/.pki/ca.pem create mode 100644 compose/README.md create mode 100644 compose/deployment/grafana/Dockerfile create mode 100644 compose/deployment/grafana/config.ini create mode 100644 compose/deployment/grafana/dashboards/dockermetrics.json create mode 100644 compose/deployment/grafana/dashboards/postgres.json create mode 100644 compose/deployment/grafana/dashboards/sdk.json create mode 100644 compose/deployment/grafana/dashboards/temporal.json create mode 100644 compose/deployment/grafana/provisioning/dashboards/all.yml create mode 100644 compose/deployment/grafana/provisioning/datasources/all.yml create mode 100644 compose/deployment/loki/local-config.yaml create mode 100644 compose/deployment/nginx/nginx.conf create mode 100644 compose/deployment/otel/otel-config.yaml create mode 100644 compose/deployment/prometheus/config.yml create mode 100644 compose/docker-compose-cass-es.yml create mode 100644 compose/docker-compose-multirole.yaml create mode 100644 compose/docker-compose-mysql-es.yml create mode 100644 compose/docker-compose-mysql.yml create mode 100644 compose/docker-compose-postgres-opensearch.yml create mode 100644 compose/docker-compose-postgres.yml create mode 100644 compose/docker-compose-tls.yml create mode 100644 compose/docker-compose-validate-multirole.yml create mode 100644 compose/docker-compose-validate.yml create mode 100644 compose/docker-compose.yml create mode 100644 compose/dynamicconfig/README.md create mode 100644 compose/dynamicconfig/development-cass.yaml create mode 100644 compose/dynamicconfig/development-sql.yaml create mode 100644 compose/dynamicconfig/docker.yaml create mode 100755 compose/scripts/create-namespace.sh create mode 100755 compose/scripts/setup-cassandra-es.sh create mode 100755 compose/scripts/setup-mysql-es.sh create mode 100755 compose/scripts/setup-mysql.sh create mode 100755 compose/scripts/setup-postgres-es-tls.sh create mode 100755 compose/scripts/setup-postgres-es.sh create mode 100755 compose/scripts/setup-postgres-opensearch.sh create mode 100755 compose/scripts/setup-postgres.sh create mode 100755 compose/scripts/validate-temporal.sh create mode 100644 compose/tls/Dockerfile.admin-tools-tls create mode 100644 compose/tls/Dockerfile.auto-setup-tls create mode 100644 compose/tls/Dockerfile.tls create mode 100644 compose/tls/README.md create mode 100755 compose/tls/run-tls.sh diff --git a/.github/actionlint-matcher.json b/.github/actionlint-matcher.json new file mode 100644 index 0000000..4613e16 --- /dev/null +++ b/.github/actionlint-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "actionlint", + "pattern": [ + { + "regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$", + "file": 1, + "line": 2, + "column": 3, + "message": 4, + "code": 5 + } + ] + } + ] +} diff --git a/.github/workflows/compose.yaml b/.github/workflows/compose.yaml new file mode 100644 index 0000000..3d8f2be --- /dev/null +++ b/.github/workflows/compose.yaml @@ -0,0 +1,173 @@ +name: Test compose examples + +on: + pull_request: + paths: + - 'compose/**' + - '.github/workflows/compose.yaml' + push: + branches: + - main + paths: + - 'compose/**' + - '.github/workflows/compose.yaml' + +permissions: + contents: read + +jobs: + lint-actions: + name: Lint GitHub Actions workflows + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Lint actions + run: | + echo "::add-matcher::.github/actionlint-matcher.json" + bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + ./actionlint -color + shell: bash + + compose-test: + name: Test ${{ matrix.compose-file }} + needs: lint-actions + strategy: + fail-fast: false + matrix: + compose-file: + - docker-compose.yml + - docker-compose-postgres.yml + - docker-compose-mysql.yml + - docker-compose-mysql-es.yml + - docker-compose-cass-es.yml + - docker-compose-postgres-opensearch.yml + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Print build information + env: + HEAD_REF: ${{ github.head_ref }} + REF: ${{ github.ref }} + COMPOSE_FILE: ${{ matrix.compose-file }} + run: echo "head_ref=$HEAD_REF ref=$REF compose=$COMPOSE_FILE" + + - uses: actions/checkout@v6 + + - name: Start compose stack + working-directory: compose + run: docker compose -f ${{ matrix.compose-file }} up -d + + - name: Run validation + working-directory: compose + run: | + docker compose -f ${{ matrix.compose-file }} -f docker-compose-validate.yml up temporal-validate --exit-code-from temporal-validate + + - name: Print all logs on failure + if: failure() + working-directory: compose + run: | + echo "=== Printing all container logs ===" + docker compose -f ${{ matrix.compose-file }} ps -a + docker compose -f ${{ matrix.compose-file }} logs + + - name: Cleanup + if: always() + working-directory: compose + run: docker compose -f ${{ matrix.compose-file }} -f docker-compose-validate.yml down -v + + compose-tls-test: + name: Test docker-compose-tls.yml + needs: lint-actions + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Print build information + env: + HEAD_REF: ${{ github.head_ref }} + REF: ${{ github.ref }} + run: echo "head_ref=$HEAD_REF ref=$REF compose=docker-compose-tls.yml" + + - uses: actions/checkout@v6 + + - name: Generate TLS certificates + working-directory: compose + run: | + docker build -t temporal_tls:test -f tls/Dockerfile.tls . + mkdir -p .pki + docker run --rm -v temporal_tls_pki:/pki -v "${PWD}"/.pki:/pki-out temporal_tls:test + + - name: Build TLS images + working-directory: compose + run: COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml build --no-cache + + - name: Start TLS compose stack + working-directory: compose + run: COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml up -d + + - name: Run validation + working-directory: compose + run: | + COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml -f docker-compose-validate.yml up temporal-validate --exit-code-from temporal-validate + + - name: Print all logs on failure + if: failure() + working-directory: compose + run: | + echo "=== Printing all container logs ===" + COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml ps -a + COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml logs + + - name: Cleanup + if: always() + working-directory: compose + run: | + COMPOSE_PROJECT_NAME=tls_test docker compose -f docker-compose-tls.yml -f docker-compose-validate.yml down -v + docker volume rm temporal_tls_pki || true + rm -rf .pki + + compose-multirole-test: + name: Test docker-compose-multirole.yaml + needs: lint-actions + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Print build information + env: + HEAD_REF: ${{ github.head_ref }} + REF: ${{ github.ref }} + run: echo "head_ref=$HEAD_REF ref=$REF compose=docker-compose-multirole.yaml" + + - uses: actions/checkout@v6 + + - name: Install loki Docker plugin + run: docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions + + - name: Start multirole compose stack + working-directory: compose + run: docker compose -f docker-compose-multirole.yaml up -d + + - name: Run validation + working-directory: compose + run: | + docker compose -f docker-compose-multirole.yaml -f docker-compose-validate-multirole.yml up temporal-validate --exit-code-from temporal-validate + + - name: Verify temporal services are running + working-directory: compose + run: | + docker compose -f docker-compose-multirole.yaml ps temporal-history temporal-frontend temporal-matching temporal-worker + + - name: Print all logs on failure + if: failure() + working-directory: compose + run: | + echo "=== Printing all container logs ===" + docker compose -f docker-compose-multirole.yaml ps -a + docker compose -f docker-compose-multirole.yaml logs + + - name: Cleanup + if: always() + working-directory: compose + run: docker compose -f docker-compose-multirole.yaml -f docker-compose-validate-multirole.yml down -v diff --git a/.github/workflows/extensibility.yaml b/.github/workflows/extensibility.yaml index 641fb05..2796e86 100644 --- a/.github/workflows/extensibility.yaml +++ b/.github/workflows/extensibility.yaml @@ -17,10 +17,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Print build information - run: 'echo head_ref: ${{ github.head_ref }}, ref: ${{ github.ref }}, os: ${{ matrix.os }}' - - uses: actions/checkout@v2 + env: + HEAD_REF: ${{ github.head_ref }} + REF: ${{ github.ref }} + OS: ${{ matrix.os }} + run: echo "head_ref=$HEAD_REF ref=$REF os=$OS" + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v3.0.0 + uses: actions/setup-go@v6 with: go-version: '1.22' - name: build diff --git a/.github/workflows/promql-to-dd-go_build-publish.yaml b/.github/workflows/promql-to-dd-go_build-publish.yaml index f93329b..57228d4 100644 --- a/.github/workflows/promql-to-dd-go_build-publish.yaml +++ b/.github/workflows/promql-to-dd-go_build-publish.yaml @@ -15,13 +15,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Log in to registry # This is where you will update the personal access token to GITHUB_TOKEN @@ -29,7 +29,7 @@ jobs: - name: Setup Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} @@ -41,7 +41,7 @@ jobs: type=sha - name: Build and Push - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v6 with: context: cloud/observability/promql-to-dd-go tags: ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/promql-to-dd-go_test.yaml b/.github/workflows/promql-to-dd-go_test.yaml index a867839..1edbe7a 100644 --- a/.github/workflows/promql-to-dd-go_test.yaml +++ b/.github/workflows/promql-to-dd-go_test.yaml @@ -15,10 +15,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Print build information - run: 'echo head_ref: ${{ github.head_ref }}, ref: ${{ github.ref }}, os: ${{ matrix.os }}' - - uses: actions/checkout@v2 + env: + HEAD_REF: ${{ github.head_ref }} + REF: ${{ github.ref }} + OS: ${{ matrix.os }} + run: echo "head_ref=$HEAD_REF ref=$REF os=$OS" + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v3.0.0 + uses: actions/setup-go@v6 with: go-version: '1.20' - name: build diff --git a/.github/workflows/promql-to-scrape.yaml b/.github/workflows/promql-to-scrape.yaml index ec71e07..1a4b65a 100644 --- a/.github/workflows/promql-to-scrape.yaml +++ b/.github/workflows/promql-to-scrape.yaml @@ -24,13 +24,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to GitHub Container Registry uses: docker/login-action@v3 @@ -41,7 +41,7 @@ jobs: - name: Setup Docker metadata id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} @@ -53,7 +53,7 @@ jobs: type=sha - name: Build and Push - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v6 with: context: cloud/observability/promql-to-scrape tags: ${{ steps.meta.outputs.tags }} diff --git a/README.md b/README.md index 38e490a..472dfc5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Temporal Customization Samples -These samples show how to customize Temporal server for specific production scenarios. +# Temporal Server Samples +These samples show how to run and customize Temporal server for local development and production scenarios. Learn more about Temporal at: * Documentation: https://docs.temporal.io @@ -16,6 +16,7 @@ Please follow instructions from README.md file in every sample directory. ## Samples +- **[Docker Compose](./compose/)**: docker-compose files to run a local Temporal Server with various database and dependency configurations (PostgreSQL, MySQL, Cassandra, Elasticsearch, OpenSearch). - **[TLS](./tls/)**: how to configure Transport Layer Security (TLS) to secure network communication with and within Temporal cluster. - **[Authorizer](./extensibility/authorizer)**: how to inject a low-level authorizer component that can control access to all API calls. diff --git a/compose/.env b/compose/.env new file mode 100644 index 0000000..ee444ef --- /dev/null +++ b/compose/.env @@ -0,0 +1,12 @@ +COMPOSE_PROJECT_NAME=temporal +CASSANDRA_VERSION=3.11.9 +ELASTICSEARCH_VERSION=7.17.27 +MYSQL_VERSION=8 +TEMPORAL_VERSION=1.29.1 +TEMPORAL_ADMINTOOLS_VERSION=1.29.1-tctl-1.18.4-cli-1.5.0 +TEMPORAL_UI_VERSION=2.34.0 +POSTGRESQL_VERSION=16 +POSTGRES_PASSWORD=temporal +POSTGRES_USER=temporal +POSTGRES_DEFAULT_PORT=5432 +OPENSEARCH_VERSION=2.5.0 diff --git a/compose/.pki/ca.pem b/compose/.pki/ca.pem new file mode 100644 index 0000000..0c3da5d --- /dev/null +++ b/compose/.pki/ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIUcE+9Bob3MuRpMzBXMExXFztYvV8wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAxMCQ0EwHhcNMjUxMjE2MTgwMjAwWhcNMzAxMjE1MTgwMjAw +WjANMQswCQYDVQQDEwJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AM9VopN8jDN7AR1mY96FMtWVrlKCEQoXdxxb1wqyDAar1rrH5svtOTBvmwo00v+v +I8i1Ord1u2p54sW2a4MdEaEaQwpDbCRDOl285/H8xsSXQGskbTIuqAnQXv00+Pld +UptDK28P6E/1BCmhiSju4olrgzlSzN124MKoSeJ36TJ+gToLRMNey8RV4HgVVlZa +pmXa+SLwn8ssBM14yYyuj1wxtVEp15DSIwXlet2Du0+AIMsSK5rxd/GDl6nrvQt6 +TwL0MYV1FoVwMtV8SDpmy7u2CsgvbTcCxBvr3pwSUh+6r10K5wfDtMTZ4eIaI8jg +0T9SGJZW3oOoUgjANnJ/McMCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMyu2ChnE9nDq46qxFtHOkfdUFK+MA0GCSqG +SIb3DQEBCwUAA4IBAQCNzqimKll1I23xRgr1Cqe008W3fTiM1g4Z+7kpt/kYzseE +obkzswWeNSEHHgBwMvHHTkLm7ftMZ+FLsNC/DNb3uSVu6oUcTzW461QTzrz9t02s +1w8ZfMrqsAWHPHEN5/ESGwSYO7cW7ISEkD3PHppX7mxHw38u589TvBBXtjXqx6Zv +p4bInVjRyL7qf/Byw8SDJXNSWfjEhQOAN2NuMmjMuXJaEVMf6eh95EfVO6KhArD9 +rJ97OqnTQWsJO3NOAVd2R4nxcgi6/3XZRkISf33XwXMUyIlw2rxzXFv/WSgMVFCl +Mc41TvvkexS1NTMJmj2hn7j9U/w4NhNoI/G3t7zm +-----END CERTIFICATE----- diff --git a/compose/README.md b/compose/README.md new file mode 100644 index 0000000..e206516 --- /dev/null +++ b/compose/README.md @@ -0,0 +1,180 @@ +# Temporal Server docker-compose files + +These docker-compose files enable you to run a local instance of the Temporal Server. +There are a variety of docker-compose files, each utilizing a different set of dependencies. + +## Prerequisites + +To use these files, you must first have the following installed: + +- [Docker](https://docs.docker.com/engine/installation/) +- [docker-compose](https://docs.docker.com/compose/install/) + +## How to use + +The following steps will run a local instance of the Temporal Server using the default configuration file (`docker-compose.yml`): + +1. Clone this repository. +2. Change directory into the root of the project. +3. Run the `docker-compose up` command. + +```bash +git clone https://github.com/temporalio/samples-server.git +cd samples-server/compose +docker-compose up +``` + +> ⚠️ If you are on an M1 Mac, note that Temporal v1.12 to v1.14 had fatal issues with ARM builds. v1.14.2 onwards should be fine for M1 Macs. + +After the Server has started, you can open the Temporal Web UI in your browser: [http://localhost:8080](http://localhost:8080). + +You can also interact with the Server using a preconfigured CLI (tctl). +First create an alias for `tctl`: + +```bash +alias tctl="docker exec temporal-admin-tools tctl" +``` + +The following is an example of how to register a new namespace `test-namespace` with 1 day of retention: + +```bash +tctl --ns test-namespace namespace register -rd 1 +``` + +You can find our `tctl` docs on [docs.temporal.io](https://docs.temporal.io/docs/system-tools/tctl/). + +Get started building Workflows with a [Go sample](https://github.com/temporalio/samples-go), [Java sample](https://github.com/temporalio/samples-java), or write your own using one of the [SDKs](https://docs.temporal.io/docs/sdks-introduction). + +### Other configuration files + +The default configuration file (`docker-compose.yml`) uses a PostgreSQL database, an Elasticsearch instance, and exposes the Temporal gRPC Frontend on port 7233. +The other configuration files in the repo spin up instances of the Temporal Server using different databases and dependencies. +For example you can run the Temporal Server with MySQL and Elastic Search with this command: + +```bash +docker-compose -f docker-compose-mysql-es.yml up +``` + +Here is a list of available files and the dependencies they use. + +| File | Description | +|----------------------------------------|---------------------------------------------------------------| +| docker-compose.yml | PostgreSQL and Elasticsearch (default) | +| docker-compose-tls.yml | PostgreSQL and Elasticsearch with TLS | +| docker-compose-postgres.yml | PostgreSQL | +| docker-compose-cass-es.yml | Cassandra and Elasticsearch | +| docker-compose-mysql.yml | MySQL | +| docker-compose-mysql-es.yml | MySQL and Elasticsearch | +| docker-compose-postgres-opensearch.yml | PostgreSQL and OpenSearch | +| docker-compose-multirole.yml | PostgreSQL and Elasticsearch with mult-role Server containers | + +### Using multi-role configuration + +First install the loki plugin (this is one time operation) +```bash +docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions +``` + +Start multi-role Server configuration: +``` +docker compose -f docker-compose-multirole.yaml up +``` + +Some exposed endpoints: +- http://localhost:8080 - Temporal Web UI +- http://localhost:8085 - Grafana dashboards +- http://localhost:9090 - Prometheus UI +- http://localhost:9090/targets - Prometheus targets +- http://localhost:8000/metrics - Server metrics + +### Using the web interface + +`docker-compose.yml` includes the Temporal Web UI. + +If you run command: + +```bash +docker-compose up +``` + +You access the Temporal Web UI at http://localhost:8080. + +### Enabling metrics (with Grafana and Prometheus) + +We maintain two example docker-compose setups with server metrics enabled, and Prometheus and Grafana with [our Server and SDK dashboards](https://github.com/temporalio/dashboards): + +- https://github.com/tsurdilo/my-temporal-dockercompose +- https://github.com/temporalio/background-checks + +### Use a custom image configuration + +If you want, you can even use a custom Docker image of the Temporal Server. + +Clone the main Temporal Server repo: [https://github.com/temporalio/temporal](https://github.com/temporalio/temporal): + +```bash +git clone https://github.com/temporalio/temporal.git +``` + +In the following command, replace **** and **** to build the custom Docker image: + +```bash +git checkout +docker build . -t temporalio/server: --build-arg TARGET=server +``` + +Next, in the `docker-compose.yml` file, replace the `TEMPORAL_VERSION` value in the `.env` file with ****. + +Then run the `docker-compose up` command: + +```bash +docker-compose up +``` + +## Using Temporal docker images in production + +These docker-compose setups use the `temporalio/server` image with a separate initialization step to set up database schemas. The `temporal-admin-tools` service runs once to create and initialize the database schema, then the `temporal` service starts using `temporalio/server`. + +In a typical production setting, dependencies such as `cassandra` or `elasticsearch` are managed/started independently of the Temporal server, and schemas are set up as part of your deployment process rather than at startup. + +To use the `temporalio/server` container in a production setting, use the following command: + +```plain +docker run -e CASSANDRA_SEEDS=10.x.x.x -- csv of Cassandra server ipaddrs + -e KEYSPACE= -- Cassandra keyspace + -e VISIBILITY_KEYSPACE= -- Cassandra visibility keyspace + -e SKIP_SCHEMA_SETUP=true -- do not setup Cassandra schema during startup + -e NUM_HISTORY_SHARDS=1024 \ -- Number of history shards + -e SERVICES=history,matching \ -- Spin-up only the provided services + -e LOG_LEVEL=debug,info \ -- Logging level + -e DYNAMIC_CONFIG_FILE_PATH=config/foo.yaml -- Dynamic config file to be watched + temporalio/server: +``` + +## Server Configuration Templates + +The Temporal Server uses a base configuration template that defines the structure for persistence, visibility, and other settings. + +### Configuration template location by version + +**Pre-v1.30 (external template):** +- Configuration template: [`docker/config_template.yaml`](https://github.com/temporalio/temporal/blob/main/docker/config_template.yaml) +- The template is stored as a separate file in the Docker image +- Environment variables are substituted into this template at runtime + +**v1.30 and later (embedded template):** +- Configuration template: [`common/config/config_template_embedded.yaml`](https://github.com/temporalio/temporal/blob/main/common/config/config_template_embedded.yaml) +- The template is embedded directly in the server binary +- More efficient and reduces dependencies on external files +- Environment variable substitution works the same way + +### Impact on docker-compose configurations + +The docker-compose files in this repository work with both pre-v1.30 and v1.30+ server versions. The main differences are: + +1. **Admin tools**: v1.30+ includes improved tooling like `temporal-elasticsearch-tool` and enhanced `temporal-cassandra-tool` commands +2. **Configuration**: v1.30+ uses the embedded template, but accepts the same environment variables +3. **Schema management**: Setup scripts detect and use new tools when available, with fallback to legacy methods + +For customizing server configuration beyond environment variables, refer to the appropriate template file for your server version. + diff --git a/compose/deployment/grafana/Dockerfile b/compose/deployment/grafana/Dockerfile new file mode 100644 index 0000000..acb0eec --- /dev/null +++ b/compose/deployment/grafana/Dockerfile @@ -0,0 +1,4 @@ +FROM grafana/grafana:7.5.16 +ADD ./provisioning /etc/grafana/provisioning +ADD ./config.ini /etc/grafana/config.ini +ADD ./dashboards /var/lib/grafana/dashboards \ No newline at end of file diff --git a/compose/deployment/grafana/config.ini b/compose/deployment/grafana/config.ini new file mode 100644 index 0000000..3f58be4 --- /dev/null +++ b/compose/deployment/grafana/config.ini @@ -0,0 +1,8 @@ +[paths] +provisioning = /etc/grafana/provisioning + +[server] +enable_gzip = true + +[users] +default_theme = light \ No newline at end of file diff --git a/compose/deployment/grafana/dashboards/dockermetrics.json b/compose/deployment/grafana/dashboards/dockermetrics.json new file mode 100644 index 0000000..be7fc03 --- /dev/null +++ b/compose/deployment/grafana/dashboards/dockermetrics.json @@ -0,0 +1,1019 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Draw some docker metrics", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "description": "Number of CPUs", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 7, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.0.7", + "repeat": "instance", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "engine_daemon_engine_cpus_cpus{instance=~'$instance'}", + "intervalFactor": 2, + "legendFormat": "", + "metric": "engine_daemon_engine_cpus_cpus", + "refId": "A", + "step": 60 + } + ], + "title": "CPU Cores", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "description": "Measuring some percentiles performance", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 3 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.99, rate(engine_daemon_container_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 99", + "refId": "A", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.90, rate(engine_daemon_container_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 90", + "refId": "B", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.50, rate(engine_daemon_container_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 50", + "refId": "C", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.25, rate(engine_daemon_container_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 25", + "refId": "D", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Time x Container Action percentile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 10 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "engine_daemon_container_actions_seconds_count{instance=~'$instance'}", + "intervalFactor": 2, + "legendFormat": "{{action}}", + "metric": "engine_daemon_container_actions_seconds_count", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Container Actions", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "description": "Measuring some percentiles performance", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 17 + }, + "hiddenSeries": false, + "id": 22, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.99, rate(engine_daemon_network_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 99", + "refId": "A", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.90, rate(engine_daemon_network_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 90", + "refId": "B", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.50, rate(engine_daemon_network_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 50", + "refId": "C", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.25, rate(engine_daemon_network_actions_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "{{action}} 25", + "refId": "D", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Time x Network Action percentile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 24 + }, + "hiddenSeries": false, + "id": 19, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "engine_daemon_network_actions_seconds_count{instance=~'$instance'}", + "intervalFactor": 2, + "legendFormat": "{{action}}", + "metric": "engine_daemon_container_actions_seconds_count", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Network Actions", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "show": true + }, + { + "format": "none", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "description": "Measuring histogram on some percentile", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 31 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "99", + "refId": "D", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.90, rate(etcd_disk_wal_fsync_duration_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "90", + "refId": "A", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.50, rate(etcd_disk_wal_fsync_duration_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "50", + "refId": "B", + "step": 4 + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "histogram_quantile(0.10, rate(etcd_disk_wal_fsync_duration_seconds_bucket{instance=~'$instance'}[$interval]))", + "intervalFactor": 2, + "legendFormat": "10", + "refId": "C", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "etcd fsync wall percentile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "decimals": 0, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "expr": "engine_daemon_events_subscribers_total{instance=~'$instance'}", + "intervalFactor": 2, + "legendFormat": " ", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Event Subscribers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "decimals": 0, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 45 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "9.0.7", + "pointradius": 5, + "points": false, + "renderer": "flot", + "repeat": "instance", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Image Builds", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "schemaVersion": 36, + "style": "dark", + "tags": [ + "docker", + "docker metrics", + "docker engine" + ], + "templating": { + "list": [ + { + "auto": true, + "auto_count": 30, + "auto_min": "10s", + "current": { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + "hide": 0, + "label": "Interval", + "name": "interval", + "options": [ + { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "2m", + "value": "2m" + }, + { + "selected": false, + "text": "3m", + "value": "3m" + }, + { + "selected": false, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "7m", + "value": "7m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": false, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + }, + { + "selected": false, + "text": "7d", + "value": "7d" + }, + { + "selected": false, + "text": "14d", + "value": "14d" + }, + { + "selected": false, + "text": "30d", + "value": "30d" + } + ], + "query": "30s,1m,2m,3m,5m,7m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "queryValue": "", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + }, + { + "current": { + "selected": true, + "text": [], + "value": [] + }, + "datasource": { + "uid": "$datasource" + }, + "definition": "", + "error": { + "message": "Datasource $datasource was not found" + }, + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": true, + "name": "instance", + "options": [], + "query": "engine_daemon_engine_info", + "refresh": 1, + "regex": "/instance=\"([^\"]+)\"/", + "skipUrlSync": false, + "sort": 0, + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Docker Engine Metrics", + "uid": "ngW7QSi4k", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/compose/deployment/grafana/dashboards/postgres.json b/compose/deployment/grafana/dashboards/postgres.json new file mode 100644 index 0000000..c2cf938 --- /dev/null +++ b/compose/deployment/grafana/dashboards/postgres.json @@ -0,0 +1,3153 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "Dashboard for postgres_exporter prometheus metrics", + "editable": true, + "gnetId": 9628, + "graphTooltip": 0, + "id": null, + "iteration": 1547234558060, + "links": [], + "panels": [ + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 34, + "panels": [], + "title": "General Counters, CPU, Memory and File Descriptor Stats", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#7eb26d", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 0, + "y": 1 + }, + "id": 36, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_static{release=\"$release\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{short_version}}", + "refId": "A" + } + ], + "thresholds": "", + "title": "Version", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "name" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "start time of the process", + "format": "dateTimeFromNow", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 4, + "y": 1 + }, + "id": 28, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "110%", + "prefix": "", + "prefixFontSize": "110%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "process_start_time_seconds{release=\"$release\", instance=\"$instance\"} * 1000", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Start Time", + "type": "singlestat", + "valueFontSize": "110%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "decbytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 8, + "y": 1 + }, + "height": "200px", + "id": 10, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "SUM(pg_stat_database_tup_fetched{datname=~\"$datname\", instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Current fetch data", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "decbytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 12, + "y": 1 + }, + "height": "200px", + "id": 11, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "SUM(pg_stat_database_tup_inserted{release=\"$release\", datname=~\"$datname\", instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Current insert data", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "decbytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 16, + "y": 1 + }, + "height": "200px", + "id": 12, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "SUM(pg_stat_database_tup_updated{datname=~\"$datname\", instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Current update data", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 2, + "w": 4, + "x": 20, + "y": 1 + }, + "id": 38, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_max_connections{release=\"$release\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Max Connections", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "Average user and system CPU time spent in seconds.", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 3 + }, + "id": 22, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(rate(process_cpu_seconds_total{release=\"$release\", instance=\"$instance\"}[5m]) * 1000)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "CPU Time", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Average CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "Virtual and Resident memory size in bytes, averages over 5 min interval", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 3 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(rate(process_resident_memory_bytes{release=\"$release\", instance=\"$instance\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Resident Mem", + "refId": "A" + }, + { + "expr": "avg(rate(process_virtual_memory_bytes{release=\"$release\", instance=\"$instance\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Virtual Mem", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Average Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "Number of open file descriptors", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 3 + }, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_open_fds{release=\"$release\", instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Open FD", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Open File Descriptors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 32, + "panels": [], + "title": "Settings", + "type": "row" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 11 + }, + "id": 40, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_shared_buffers_bytes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Shared Buffers", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 3, + "y": 11 + }, + "id": 42, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_effective_cache_size_bytes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Effective Cache", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 6, + "y": 11 + }, + "id": 44, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_maintenance_work_mem_bytes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Maintenance Work Mem", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 9, + "y": 11 + }, + "id": 46, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_work_mem_bytes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "Work Mem", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "decimals": 1, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 12, + "y": 11 + }, + "id": 48, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_max_wal_size_bytes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Max WAL Size", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 15, + "y": 11 + }, + "id": 50, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_random_page_cost{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Random Page Cost", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 18, + "y": 11 + }, + "id": 52, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_seq_page_cost", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Seq Page Cost", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 20, + "y": 11 + }, + "id": 54, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_max_worker_processes{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Max Worker Processes", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 2, + "x": 22, + "y": 11 + }, + "id": 56, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "pg_settings_max_parallel_workers{instance=\"$instance\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "title": "Max Parallel Workers", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 30, + "panels": [], + "title": "Database Stats", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 15 + }, + "id": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_activity_count{datname=~\"$datname\", instance=~\"$instance\", state=\"active\"} !=0", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{datname}}, s: {{state}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Active sessions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 15 + }, + "id": 60, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(pg_stat_database_xact_commit{instance=\"$instance\", datname=~\"$datname\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{datname}} commits", + "refId": "A" + }, + { + "expr": "irate(pg_stat_database_xact_rollback{instance=\"$instance\", datname=~\"$datname\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{datname}} rollbacks", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Transactions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 15 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_tup_updated{datname=~\"$datname\", instance=~\"$instance\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Update data", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 22 + }, + "id": 5, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_tup_fetched{datname=~\"$datname\", instance=~\"$instance\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Fetch data (SELECT)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 22 + }, + "id": 6, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_tup_inserted{datname=~\"$datname\", instance=~\"$instance\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Insert data", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "decimals": 0, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 22 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_locks_count{datname=~\"$datname\", instance=~\"$instance\", mode=~\"$mode\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}},{{mode}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Lock tables", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 29 + }, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "total", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_tup_returned{datname=~\"$datname\", instance=~\"$instance\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Return data", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 29 + }, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": false, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_activity_count{datname=~\"$datname\", instance=~\"$instance\", state=~\"idle|idle in transaction|idle in transaction (aborted)\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}, s: {{state}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Idle sessions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 29 + }, + "id": 7, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_tup_deleted{datname=~\"$datname\", instance=~\"$instance\"} != 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{datname}}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Delete data", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "decimals": 2, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 36 + }, + "id": 62, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pg_stat_database_blks_hit{instance=\"$instance\", datname=~\"$datname\"} / (pg_stat_database_blks_read{instance=\"$instance\", datname=~\"$datname\"} + pg_stat_database_blks_hit{instance=\"$instance\", datname=~\"$datname\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ datname }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Cache Hit Rate", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 4, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 36 + }, + "id": 64, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(pg_stat_bgwriter_buffers_backend{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "buffers_backend", + "refId": "A" + }, + { + "expr": "irate(pg_stat_bgwriter_buffers_alloc{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "buffers_alloc", + "refId": "B" + }, + { + "expr": "irate(pg_stat_bgwriter_buffers_backend_fsync{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "backend_fsync", + "refId": "C" + }, + { + "expr": "irate(pg_stat_bgwriter_buffers_checkpoint{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "buffers_checkpoint", + "refId": "D" + }, + { + "expr": "irate(pg_stat_bgwriter_buffers_clean{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "buffers_clean", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Buffers (bgwriter)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "decimals": 0, + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 36 + }, + "id": 66, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(pg_stat_database_conflicts{instance=\"$instance\", datname=~\"$datname\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{datname}} conflicts", + "refId": "B" + }, + { + "expr": "irate(pg_stat_database_deadlocks{instance=\"$instance\", datname=~\"$datname\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{datname}} deadlocks", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Conflicts/Deadlocks", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "Total amount of data written to temporary files by queries in this database. All temporary files are counted, regardless of why the temporary file was created, and regardless of the log_temp_files setting.", + "fill": 1, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 43 + }, + "id": 68, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(pg_stat_database_temp_bytes{instance=\"$instance\", datname=~\"$datname\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{datname}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Temp File (Bytes)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "fill": 1, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 43 + }, + "id": 70, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(pg_stat_bgwriter_checkpoint_write_time{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "write_time - Total amount of time that has been spent in the portion of checkpoint processing where files are written to disk.", + "refId": "B" + }, + { + "expr": "irate(pg_stat_bgwriter_checkpoint_sync_time{instance=\"$instance\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "sync_time - Total amount of time that has been spent in the portion of checkpoint processing where files are synchronized to disk.", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Checkpoint Stats", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 16, + "style": "dark", + "tags": [ + "postgres", + "db", + "stats" + ], + "templating": { + "list": [ + { + "auto": true, + "auto_count": 200, + "auto_min": "1s", + "current": { + "text": "auto", + "value": "$__auto_interval_interval" + }, + "hide": 0, + "label": "Interval", + "name": "interval", + "options": [ + { + "selected": true, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "1s", + "value": "1s" + }, + { + "selected": false, + "text": "5s", + "value": "5s" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "5m", + "value": "5m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + } + ], + "query": "1s,5s,1m,5m,1h,6h,1d", + "refresh": 2, + "type": "interval" + }, + { + "allValue": null, + "current": {}, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": 0, + "includeAll": false, + "label": "Namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": "query_result(pg_exporter_last_scrape_duration_seconds)", + "refresh": 2, + "regex": "/.*kubernetes_namespace=\"([^\"]+).*/", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": 0, + "includeAll": false, + "label": "Release", + "multi": false, + "name": "release", + "options": [], + "query": "query_result(pg_exporter_last_scrape_duration_seconds{kubernetes_namespace=\"$namespace\"})", + "refresh": 2, + "regex": "/.*release=\"([^\"]+)/", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": 0, + "includeAll": false, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": "query_result(up{release=\"$release\"})", + "refresh": 1, + "regex": "/.*instance=\"([^\"]+).*/", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": 0, + "includeAll": true, + "label": "Database", + "multi": true, + "name": "datname", + "options": [], + "query": "label_values(datname)", + "refresh": 1, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": 0, + "includeAll": true, + "label": "Lock table", + "multi": true, + "name": "mode", + "options": [], + "query": "label_values({mode=~\"accessexclusivelock|accesssharelock|exclusivelock|rowexclusivelock|rowsharelock|sharelock|sharerowexclusivelock|shareupdateexclusivelock\"}, mode)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "PostgreSQL Database", + "uid": "000000039", + "version": 13 +} \ No newline at end of file diff --git a/compose/deployment/grafana/dashboards/sdk.json b/compose/deployment/grafana/dashboards/sdk.json new file mode 100644 index 0000000..a39e786 --- /dev/null +++ b/compose/deployment/grafana/dashboards/sdk.json @@ -0,0 +1,2025 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "iteration": 1642562334429, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 8, + "panels": [], + "title": "RPC Overview ($Namespace)", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum(rate(temporal_request_latency_seconds_bucket[5m]))", + "interval": "", + "legendFormat": "requests", + "refId": "A" + }, + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum(rate(temporal_request_latency_seconds_bucket[5m]))", + "hide": false, + "interval": "", + "legendFormat": "failures", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Requests Vs Failures", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 7, + "x": 8, + "y": 1 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (operation) ((rate(temporal_request_latency_seconds_bucket[5m])))", + "interval": "", + "legendFormat": "{{operation }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "RPC Requests Per Operation", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 9, + "x": 15, + "y": 1 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (operation) (rate(temporal_request_latency_seconds_bucket[5m]))", + "interval": "", + "legendFormat": "{{operation }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "RPC Failures Per Operation", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum by (namespace, operation, le) (rate(temporal_request_latency_seconds_bucket[5m])))", + "interval": "", + "legendFormat": "{{ namespace }} - {{operation }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "RPC Latencies ($Namespace)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 12, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "rate(temporal_workflow_completed_total[5m])", + "interval": "", + "legendFormat": "{{ workflow_type }}", + "refId": "A" + }, + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum(rate(temporal_workflow_failed_total[5m]))", + "hide": false, + "interval": "", + "legendFormat": "failed", + "refId": "B" + }, + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum(rate(temporal_workflow_canceled_total[5m]))", + "hide": false, + "interval": "", + "legendFormat": "cancelled", + "refId": "C" + }, + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum(rate(temporal_workflow_continue_as_new_total[5m]))", + "hide": false, + "interval": "", + "legendFormat": "continued_as_new", + "refId": "D" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Completion", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_workflow_endtoend_latency_seconds_bucket[5m])) by (namespace, workflow_type, le))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ workflow_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow End-To-End Latencies", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 29 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace, workflow_type) (rate(temporal_workflow_completed_total[5m]))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ workflow_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Success By Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 29 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace, task_queue) (rate(temporal_workflow_task_schedule_to_start_latency_seconds_bucket[5m]))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ task_queue }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Task End-to-End Latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "title": "Workflows", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 20, + "panels": [], + "title": "Workflow Task Processing", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace, workflow_type) (rate(temporal_workflow_failed_total[5m]))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ workflow_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Fail by Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 22 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace) (rate(temporal_workflow_task_queue_poll_succeed_total[5m]))", + "interval": "", + "legendFormat": "{{ namespace }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Task Throughput By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 30 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace) (rate(temporal_workflow_task_queue_poll_empty[5m]))", + "interval": "", + "legendFormat": "Empty Poll - {{ namespace }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Empty Polls", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_workflow_task_execution_latency_seconds_bucket[5m])) by (namespace, le))", + "interval": "", + "legendFormat": "{{ namespace }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Task Execution Latency By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 38 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_workflow_task_execution_latency_seconds_bucket[5m])) by (namespace, workflow_type, le))", + "interval": "", + "legendFormat": "{{ namespace }} -- {{ workflow_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Workflow Task Backlog By Workflow Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 42, + "panels": [], + "title": "Activities", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 47 + }, + "hiddenSeries": false, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace) (rate(temporal_activity_execution_latency_seconds_count[5m]))", + "interval": "", + "legendFormat": "latency count", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity Throughput By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 47 + }, + "hiddenSeries": false, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace, activity_type) (rate(temporal_activity_execution_latency_seconds_count[5m]))", + "interval": "", + "legendFormat": "{{ activity_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity Throughput By Activity Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 55 + }, + "hiddenSeries": false, + "id": 44, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace, activity_type) (rate(temporal_activity_execution_failed_total[5m]))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ activity_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Failed Activity by Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 64 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_activity_execution_latency_seconds_bucket[5m])) by (namespace, activity_type, le))", + "interval": "", + "legendFormat": "{{ namespace }} - {{ activity_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity Execution Latencies", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 64 + }, + "hiddenSeries": false, + "id": 48, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_activity_succeed_endtoend_latency_seconds_bucket[5m])) by (namespace, activity_type, le))", + "interval": "", + "legendFormat": "{{ activity_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity End-To-End Latencies", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 34, + "panels": [], + "title": "Activity Task Processing", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 73 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "sum by (namespace) (rate(temporal_activity_poll_no_task[5m]))", + "interval": "", + "legendFormat": "{{ namespace }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Empty Activity Polls By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 73 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_activity_schedule_to_start_latency_seconds_bucket[5m])) by (namespace, le))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity Task Backlog By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurationms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 81 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.3.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": "$datasource", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(temporal_activity_schedule_to_start_latency_seconds_bucket[5m])) by (namespace, activity_type, le))", + "interval": "", + "legendFormat": "{{ activity_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Activity Task Backlog By Activity Type", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurationms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "schemaVersion": 34, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "default", + "value": "default" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": ".*", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "hide": 0, + "includeAll": true, + "multi": false, + "name": "Namespace", + "options": [ + { + "selected": true, + "text": "All", + "value": "$__all" + } + ], + "query": "", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "allValue": ".*", + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "hide": 0, + "includeAll": true, + "multi": false, + "name": "WorkflowType", + "options": [ + { + "selected": true, + "text": "All", + "value": "$__all" + } + ], + "query": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "30s" + ] + }, + "timezone": "", + "title": "Temporal SDK Metrics", + "uid": "XXEJjl17k", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/compose/deployment/grafana/dashboards/temporal.json b/compose/deployment/grafana/dashboards/temporal.json new file mode 100644 index 0000000..e3a0d61 --- /dev/null +++ b/compose/deployment/grafana/dashboards/temporal.json @@ -0,0 +1,3631 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Temporal Server Metrics", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 36, + "iteration": 1642302431371, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 11, + "panels": [], + "title": "Temporal", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "100 - (sum(rate(service_errors[2m]) OR on() vector(0)) / sum(rate(service_requests[2m])) * 100)", + "interval": "", + "legendFormat": "availability", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service Availability (Based on Frontend Calls)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "cacheTimeout": null, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "100 - (sum (rate(persistence_errors[2m]) OR on() vector(0)) /sum (rate(persistence_requests[2m])) * 100)", + "interval": "", + "legendFormat": "availability", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Persistence Availability", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 6, + "x": 0, + "y": 10 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(service_requests{operation=~\"StartWorkflowExecution|SignalWorkflowExecution|SignalWithStartWorkflowExecution\"}[2m]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "External Events", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 6, + "x": 6, + "y": 10 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(service_requests{operation=\"AddWorkflowTask\"}[2m]))", + "interval": "", + "legendFormat": "Scheduled", + "refId": "A" + }, + { + "expr": "sum(rate(service_requests{operation=\"RecordWorkflowTaskStarted\"}[2m]))", + "interval": "", + "legendFormat": "Started", + "refId": "B" + }, + { + "expr": "sum(rate(service_requests{operation=\"RespondWorkflowTaskCompleted\"}[2m]))", + "interval": "", + "legendFormat": "Completed", + "refId": "C" + }, + { + "expr": "sum(rate(service_requests{operation=\"RespondWorkflowTaskFailed\"}[2m]))", + "interval": "", + "legendFormat": "Failed", + "refId": "D" + }, + { + "expr": "sum(rate(schedule_to_start_timeout{operation=\"TimerActiveTaskWorkflowTimeout\"}[2m]))", + "interval": "", + "legendFormat": "Sticky Task Queue Timeout", + "refId": "E" + }, + { + "expr": "sum(rate(start_to_close_timeout{operation=\"TimerActiveTaskWorkflowTimeout\"}[2m]))", + "interval": "", + "legendFormat": "Workflow Task Timeout", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Tasks", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 6, + "x": 12, + "y": 10 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(service_requests{operation=\"AddActivityTask\"}[2m]))", + "interval": "", + "legendFormat": "Scheduled", + "refId": "A" + }, + { + "expr": "sum(rate(service_requests{operation=\"RecordActivityTaskStarted\"}[2m]))", + "interval": "", + "legendFormat": "Started", + "refId": "B" + }, + { + "expr": "sum(rate(service_requests{operation=~\"RespondActivityTaskCompleted|RespondActivityTaskFailed|RespondActivityTaskCanceled\"}[2m]))", + "interval": "", + "legendFormat": "Completed", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Activities", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 6, + "x": 18, + "y": 10 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pollers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "hiddenSeries": false, + "id": 63, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(membership_changed_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "membership_changed", + "refId": "A" + }, + { + "expr": "sum(rate(sharditem_created_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_item_created", + "refId": "B" + }, + { + "expr": "sum(rate(sharditem_removed_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_item_removed", + "refId": "C" + }, + { + "expr": "sum(rate(shard_closed_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_closed", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Shard Rebalancing", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "hiddenSeries": false, + "id": 65, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "numshards_gauge", + "format": "time_series", + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ kubernetes_pod_name }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Shard Distribution", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 54, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (temporal_service_type) (restarts)", + "interval": "", + "legendFormat": "{{ temporal_service_type }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Restarts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 6, + "x": 6, + "y": 28 + }, + "hiddenSeries": false, + "id": 55, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "num_goroutines", + "interval": "", + "legendFormat": "{{kubernetes_pod_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Goroutines", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 6, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 56, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "memory_allocated", + "interval": "", + "legendFormat": "{{kubernetes_pod_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Allocated", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 28 + }, + "hiddenSeries": false, + "id": 58, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "memory_heap", + "interval": "", + "legendFormat": "{{kubernetes_pod_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Heap", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 36 + }, + "hiddenSeries": false, + "id": 57, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "memory_stack", + "interval": "", + "legendFormat": "{{kubernetes_pod_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Stack", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 36 + }, + "hiddenSeries": false, + "id": 59, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (kubernetes_pod_name) (rate(memory_num_gc[5m]))", + "interval": "", + "legendFormat": "{{kubernetes_pod_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GC Counter", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 36 + }, + "hiddenSeries": false, + "id": 61, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(memory_gc_pause_ms_bucket[5m])) by (kubernetes_pod_name, le))", + "hide": false, + "interval": "", + "legendFormat": "{{ kubernetes_pod_name }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GC Pause", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 36 + }, + "hiddenSeries": false, + "id": 66, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(state_transition_count_count[1m]))", + "hide": false, + "interval": "", + "legendFormat": "state transition", + "refId": "A" + }, + { + "exemplar": true, + "expr": "sum(rate(sharditem_created_count[1m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_item_created", + "refId": "B" + }, + { + "expr": "sum(rate(sharditem_removed_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_item_removed", + "refId": "C" + }, + { + "expr": "sum(rate(shard_closed_count[2m]))", + "hide": false, + "interval": "", + "legendFormat": "shard_closed", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "State Transition", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:277", + "format": "short", + "label": null, + "logBase": 2, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:278", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 45 + }, + "id": 48, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 2 + }, + "hiddenSeries": false, + "id": 45, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(workflow_success{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "success", + "refId": "A" + }, + { + "expr": "sum(rate(workflow_failed{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "failed", + "refId": "B" + }, + { + "expr": "sum(rate(workflow_timeout{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "timedout", + "refId": "C" + }, + { + "expr": "sum(rate(workflow_terminate{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "terminate", + "refId": "D" + }, + { + "expr": "sum(rate(workflow_cancel{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "cancelled", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Completion Overview", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 52, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (namespace) (rate(workflow_success{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "{{ namespace }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Success By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 12 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (namespace) (rate(workflow_failed{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "{{ namespace }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Failed By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "hiddenSeries": false, + "id": 49, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (namespace) (rate(workflow_timeout{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "{{ namespace }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Timedout By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "hiddenSeries": false, + "id": 50, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (namespace) (rate(workflow_terminate{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "{{ namespace }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Terminate By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 51, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (namespace) (rate(workflow_cancel{operation=\"CompletionStats\"}[15m]))", + "interval": "", + "legendFormat": "{{ namespace }} ", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Workflow Cancelled By Namespace", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Workflow Completion Stats", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 46 + }, + "id": 23, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 3 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (rate(service_requests[5m]))", + "interval": "", + "legendFormat": "requests", + "refId": "A" + }, + { + "expr": "sum (rate(service_errors[5m]))", + "interval": "", + "legendFormat": "errors", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service RequestsVs Errors ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 6, + "y": 3 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(service_requests[5m]))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service Requests Per Operation ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 12, + "y": 3 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(service_errors_entity_not_found[5m]) OR on() vector(0))", + "hide": false, + "interval": "", + "legendFormat": "Entity Not Found", + "refId": "A" + }, + { + "expr": "sum(rate(service_errors_execution_already_started[5m]) OR on() vector(0))", + "hide": false, + "interval": "", + "legendFormat": "Execution Already Started", + "refId": "B" + }, + { + "expr": "sum(rate(service_errors_resource_exhausted[5m]) OR on() vector(0))", + "hide": false, + "interval": "", + "legendFormat": "Resource Exhausted", + "refId": "C" + }, + { + "expr": "sum by (__name__) (rate({__name__=~\"service_errors_.*\"}[5m]))", + "hide": true, + "interval": "", + "legendFormat": "{{ $__name__ }}", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service Errors Break Down ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 6, + "x": 18, + "y": 3 + }, + "hiddenSeries": false, + "id": 43, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(service_errors[5m]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service Errors By Operation ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 29, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(service_latency_bucket[5m])) by (operation, le))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Service Latency ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Overview - $Service", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 47 + }, + "id": 15, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 8, + "x": 0, + "y": 48 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (rate(persistence_requests[5m]) OR on() vector(0))", + "interval": "", + "legendFormat": "requests", + "refId": "A" + }, + { + "expr": "sum (rate(persistence_errors[5m]) OR on() vector(0))", + "interval": "", + "legendFormat": "errors", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Persistence Requests Vs Errors ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 8, + "x": 8, + "y": 48 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": " sum by (operation) (rate(persistence_requests[5m]))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Persistence Requests Per Operation ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 48 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(persistence_errors[5m]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Persistence Errors By Operation ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 58 + }, + "hiddenSeries": false, + "id": 19, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.0.4", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(persistence_latency_bucket[1m])) by (operation, le))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Persistence Latency ($Service)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Persistence - $Service", + "type": "row" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 48 + }, + "id": 33, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 9, + "x": 0, + "y": 61 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(client_requests[5m]))", + "interval": "", + "legendFormat": "requests", + "refId": "A" + }, + { + "expr": "sum(rate(client_errors[5m]))", + "interval": "", + "legendFormat": "errors", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests Vs Errors ($Service -> $Client)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 7, + "x": 9, + "y": 61 + }, + "hiddenSeries": false, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(client_requests[5m]))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Client Requests Per Operation ($Service -> $Client)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 8, + "x": 16, + "y": 61 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (operation) (rate(client_errors[5m]))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Errors By Operation ($Service -> $Client)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$datasource", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 70 + }, + "hiddenSeries": false, + "id": 39, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(client_latency_bucket[5m])) by (operation, le))", + "interval": "", + "legendFormat": "{{operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Client Latency ($Service -> $Client)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "dtdurations", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Service Client - $Client", + "type": "row" + } + ], + "refresh": false, + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "default", + "value": "default" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "allvalue": null, + "current": { + "selected": false, + "text": "dilithium", + "value": "dilithium" + }, + "datasource": "$datasource", + "definition": "label_values(service_requests,cluster)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "includeall": false, + "label": null, + "multi": false, + "name": "cluster", + "options": [], + "query": { + "query": "label_values(service_requests,cluster)", + "refId": "temporal-cluster-Variable-Query" + }, + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "skipurlsync": false, + "sort": 0, + "tagsquery": "", + "tagvaluesquery": "", + "type": "query", + "usetags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "Service", + "options": [ + { + "selected": true, + "text": "All", + "value": "$__all" + }, + { + "selected": false, + "text": "frontend", + "value": "frontend" + }, + { + "selected": false, + "text": "history", + "value": "history" + }, + { + "selected": false, + "text": "matching", + "value": "matching" + }, + { + "selected": false, + "text": "worker", + "value": "worker" + } + ], + "query": "frontend,history,matching,worker", + "skipUrlSync": false, + "type": "custom" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "All", + "value": "$__all" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "Client", + "options": [ + { + "selected": true, + "text": "All", + "value": "$__all" + }, + { + "selected": false, + "text": "frontend", + "value": "frontend" + }, + { + "selected": false, + "text": "history", + "value": "history" + }, + { + "selected": false, + "text": "matching", + "value": "matching" + } + ], + "query": "frontend,history,matching", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "30s" + ] + }, + "timezone": "", + "title": "Temporal Server Metrics", + "uid": "FxWwuPinz", + "version": 3 +} \ No newline at end of file diff --git a/compose/deployment/grafana/provisioning/dashboards/all.yml b/compose/deployment/grafana/provisioning/dashboards/all.yml new file mode 100644 index 0000000..e23a61d --- /dev/null +++ b/compose/deployment/grafana/provisioning/dashboards/all.yml @@ -0,0 +1,6 @@ +- name: 'default' + org_id: 1 + folder: '' + type: 'file' + options: + folder: '/var/lib/grafana/dashboards' \ No newline at end of file diff --git a/compose/deployment/grafana/provisioning/datasources/all.yml b/compose/deployment/grafana/provisioning/datasources/all.yml new file mode 100644 index 0000000..6e6207c --- /dev/null +++ b/compose/deployment/grafana/provisioning/datasources/all.yml @@ -0,0 +1,16 @@ +apiVersion: 1 + +datasources: + - name: 'Temporal Prometheus' + type: 'prometheus' + org_id: 1 + url: 'http://prometheus:9090' + is_default: true + version: 1 + editable: true + - name: 'Loki' + type: loki + access: proxy + url: 'http://loki:3100' + jsonData: + maxLines: 1000 \ No newline at end of file diff --git a/compose/deployment/loki/local-config.yaml b/compose/deployment/loki/local-config.yaml new file mode 100644 index 0000000..c878652 --- /dev/null +++ b/compose/deployment/loki/local-config.yaml @@ -0,0 +1,57 @@ +auth_enabled: false + +server: + http_listen_port: 3100 + log_level: error + +ingester: + wal: + dir: "/tmp/wal" + lifecycler: + address: 127.0.0.1 + ring: + kvstore: + store: inmemory + replication_factor: 1 + final_sleep: 0s + chunk_idle_period: 5m + chunk_retain_period: 30s + +schema_config: + configs: + - from: 2022-11-20 + store: boltdb + object_store: filesystem + schema: v9 + index: + prefix: index_ + period: 168h + +storage_config: + boltdb: + directory: /tmp/loki/index + + filesystem: + directory: /tmp/loki/chunks + +limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 168h + +chunk_store_config: + max_look_back_period: 0 + +table_manager: + chunk_tables_provisioning: + inactive_read_throughput: 0 + inactive_write_throughput: 0 + provisioned_read_throughput: 0 + provisioned_write_throughput: 0 + index_tables_provisioning: + inactive_read_throughput: 0 + inactive_write_throughput: 0 + provisioned_read_throughput: 0 + provisioned_write_throughput: 0 + retention_deletes_enabled: false + retention_period: 0 \ No newline at end of file diff --git a/compose/deployment/nginx/nginx.conf b/compose/deployment/nginx/nginx.conf new file mode 100644 index 0000000..db1a982 --- /dev/null +++ b/compose/deployment/nginx/nginx.conf @@ -0,0 +1,95 @@ +user nginx; + +events { + worker_connections 2048; +} + +http { + grpc_connect_timeout 75; + proxy_read_timeout 1d; + proxy_connect_timeout 1d; + proxy_send_timeout 1d; + + upstream frontend_hosts { + server temporal-frontend:7237 max_fails=0; + server temporal-frontend2:7236 max_fails=0; + + keepalive 64; + keepalive_time 1d; + keepalive_timeout 75s; + keepalive_requests 100000; + } + + server { + listen 7233 http2; + location / { + grpc_pass grpc://frontend_hosts; + proxy_set_header Connection ""; + proxy_http_version 1.1; + } + + # Standard HTTP-to-gRPC status code mappings + # Ref: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + error_page 400 = @grpc_internal; + error_page 401 = @grpc_unauthenticated; + error_page 403 = @grpc_permission_denied; + error_page 404 = @grpc_unimplemented; + error_page 429 = @grpc_unavailable; + error_page 502 = @grpc_unavailable; + error_page 503 = @grpc_unavailable; + error_page 504 = @grpc_unavailable; + # NGINX-to-gRPC status code mappings + # Ref: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md + # + error_page 405 = @grpc_internal; # Method not allowed + error_page 408 = @grpc_deadline_exceeded; # Request timeout + error_page 413 = @grpc_resource_exhausted; # Payload too large + error_page 414 = @grpc_resource_exhausted; # Request URI too large + error_page 415 = @grpc_internal; # Unsupported media type; + error_page 426 = @grpc_internal; # HTTP request was sent to HTTPS port + error_page 495 = @grpc_unauthenticated; # Client certificate authentication error + error_page 496 = @grpc_unauthenticated; # Client certificate not presented + error_page 497 = @grpc_internal; # HTTP request was sent to mutual TLS port + error_page 500 = @grpc_internal; # Server error + error_page 501 = @grpc_internal; # Not implemented + # gRPC error responses + # Ref: https://github.com/grpc/grpc-go/blob/master/codes/codes.go + # + location @grpc_deadline_exceeded { + add_header grpc-status 4; + add_header grpc-message 'deadline exceeded'; + return 204; + } + location @grpc_permission_denied { + add_header grpc-status 7; + add_header grpc-message 'permission denied'; + return 204; + } + location @grpc_resource_exhausted { + add_header grpc-status 8; + add_header grpc-message 'resource exhausted'; + return 204; + } + location @grpc_unimplemented { + add_header grpc-status 12; + add_header grpc-message unimplemented; + return 204; + } + location @grpc_internal { + add_header grpc-status 13; + add_header grpc-message 'internal error'; + return 204; + } + location @grpc_unavailable { + add_header grpc-status 14; + add_header grpc-message unavailable; + return 204; + } + location @grpc_unauthenticated { + add_header grpc-status 16; + add_header grpc-message unauthenticated; + return 204; + } + default_type application/grpc; # Ensure gRPC for all error responses + } +} \ No newline at end of file diff --git a/compose/deployment/otel/otel-config.yaml b/compose/deployment/otel/otel-config.yaml new file mode 100644 index 0000000..8997918 --- /dev/null +++ b/compose/deployment/otel/otel-config.yaml @@ -0,0 +1,30 @@ +extensions: + memory_ballast: + size_mib: 512 + zpages: + endpoint: 0.0.0.0:55679 + +receivers: + otlp: + protocols: + grpc: + http: + +processors: + batch: + +exporters: + logging: + logLevel: debug + jaeger: + endpoint: jaeger-all-in-one:14250 + tls: + insecure: true + +service: + pipelines: + traces: + receivers: [ otlp ] + processors: [ batch ] + exporters: [ jaeger ] + extensions: [ memory_ballast, zpages ] \ No newline at end of file diff --git a/compose/deployment/prometheus/config.yml b/compose/deployment/prometheus/config.yml new file mode 100644 index 0000000..da6e30b --- /dev/null +++ b/compose/deployment/prometheus/config.yml @@ -0,0 +1,41 @@ +global: + scrape_interval: 10s +scrape_configs: + - job_name: 'temporalmetrics' + metrics_path: /metrics + scheme: http + static_configs: + # Server metrics target + - targets: + - 'host.docker.internal:8000' + - 'host.docker.internal:8001' + - 'host.docker.internal:8002' + - 'host.docker.internal:8003' + - 'host.docker.internal:8004' + labels: + group: 'server-metrics' + + # Local app targets (if configured) + - targets: + - 'host.docker.internal:8077' + - 'host.docker.internal:8078' + labels: + group: 'sdk-metrics' + # Docker metrics + - targets: + - 'host.docker.internal:9323' + labels: + group: 'docker-metrics' + # Postgres Exporter + - targets: + - 'host.docker.internal:9187' + labels: + group: 'postgres-metrics' + - job_name: 'springbootjavasdk' + metrics_path: /actuator/prometheus + scheme: http + static_configs: + - targets: + - 'host.docker.internal:3030' + labels: + group: 'spring-boot-metrics' \ No newline at end of file diff --git a/compose/docker-compose-cass-es.yml b/compose/docker-compose-cass-es.yml new file mode 100644 index 0000000..8f635db --- /dev/null +++ b/compose/docker-compose-cass-es.yml @@ -0,0 +1,123 @@ +services: + cassandra: + image: cassandra:${CASSANDRA_VERSION} + container_name: temporal-cassandra + ports: + - "9042:9042" + environment: + CASSANDRA_LISTEN_ADDRESS: 127.0.0.1 + networks: + - temporal-network + healthcheck: + test: ["CMD", "cqlsh", "-e", "describe keyspaces"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + elasticsearch: + image: elasticsearch:${ELASTICSEARCH_VERSION} + container_name: temporal-elasticsearch + ports: + - "9200:9200" + environment: + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms256m -Xmx256m + - xpack.security.enabled=false + networks: + - temporal-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + cassandra: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + - CASSANDRA_SEEDS=cassandra + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_SCHEME=http + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-cassandra-es.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - CASSANDRA_SEEDS=cassandra + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-cass.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-multirole.yaml b/compose/docker-compose-multirole.yaml new file mode 100644 index 0000000..c95bcfb --- /dev/null +++ b/compose/docker-compose-multirole.yaml @@ -0,0 +1,400 @@ +x-logging: &loki-logging + logging: + driver: loki + options: + loki-url: "http://host.docker.internal:3100/loki/api/v1/push" + mode: non-blocking + max-buffer-size: 4m + loki-retries: "3" + +services: + loki: + container_name: loki + image: grafana/loki:latest + ports: + - published: 3100 + target: 3100 + command: -config.file=/etc/loki/local-config.yaml + volumes: + - type: bind + source: ./deployment/loki/local-config.yaml + target: /etc/loki/local-config.yaml + depends_on: + - grafana + networks: + - temporal-network + + elasticsearch: + <<: *loki-logging + container_name: temporal-elasticsearch + environment: + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms512m -Xmx512m + - xpack.security.enabled=false + image: elasticsearch:${ELASTICSEARCH_VERSION} + ports: + - published: 9200 + target: 9200 + networks: + - temporal-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + postgresql: + <<: *loki-logging + container_name: temporal-postgresql + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_USER: ${POSTGRES_USER} + image: postgres:${POSTGRESQL_VERSION} + expose: + - ${POSTGRES_DEFAULT_PORT} + volumes: + - /var/lib/postgresql/data + networks: + - temporal-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-setup: + <<: *loki-logging + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-setup + restart: on-failure:6 + depends_on: + postgresql: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - SQL_PASSWORD=${POSTGRES_PASSWORD} + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_SCHEME=http + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-postgres-es.sh + + temporal-history: + <<: *loki-logging + container_name: temporal-history + depends_on: + temporal-setup: + condition: service_completed_successfully + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - TEMPORAL_HISTORY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - TEMPORAL_VISIBILITY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - SERVICES=history + - PROMETHEUS_ENDPOINT=0.0.0.0:8000 + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/server:${TEMPORAL_VERSION} + ports: + - published: 7234 + target: 7234 + - published: 8000 + target: 8000 + restart: on-failure + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - temporal-network + + temporal-matching: + <<: *loki-logging + container_name: temporal-matching + depends_on: + - temporal-history + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - TEMPORAL_HISTORY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - TEMPORAL_VISIBILITY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - SERVICES=matching + - PROMETHEUS_ENDPOINT=0.0.0.0:8001 + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/server:${TEMPORAL_VERSION} + ports: + - published: 7235 + target: 7235 + - published: 8001 + target: 8001 + restart: on-failure + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - temporal-network + + temporal-frontend: + <<: *loki-logging + container_name: temporal-frontend + depends_on: + - temporal-matching + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - TEMPORAL_HISTORY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - TEMPORAL_VISIBILITY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - SERVICES=frontend + - FRONTEND_GRPC_PORT=7237 + - PROMETHEUS_ENDPOINT=0.0.0.0:8002 + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/server:${TEMPORAL_VERSION} + ports: + - published: 7237 + target: 7237 + - published: 8002 + target: 8002 + restart: on-failure + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - temporal-network + + temporal-frontend2: + <<: *loki-logging + container_name: temporal-frontend2 + depends_on: + - temporal-matching + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - TEMPORAL_HISTORY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - TEMPORAL_VISIBILITY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - SERVICES=frontend + # set different frontend grpc port + - FRONTEND_GRPC_PORT=7236 + # set different membership port than temporal-frontend + - FRONTEND_MEMBERSHIP_PORT=6936 + - PROMETHEUS_ENDPOINT=0.0.0.0:8004 + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/server:${TEMPORAL_VERSION} + ports: + - published: 7236 + target: 7236 + - published: 8004 + target: 8004 + restart: on-failure + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - temporal-network + + temporal-worker: + <<: *loki-logging + container_name: temporal-worker + depends_on: + - temporal-nginx + environment: + - DB=postgres12 + - DB_PORT=${POSTGRES_DEFAULT_PORT} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PWD=${POSTGRES_PASSWORD} + - POSTGRES_SEEDS=postgresql + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - TEMPORAL_HISTORY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - TEMPORAL_VISIBILITY_NAMESPACEDEFAULT_ARCHIVAL_FILESTORE=enabled + - SERVICES=worker + - PROMETHEUS_ENDPOINT=0.0.0.0:8003 + # set to nginx + - PUBLIC_FRONTEND_ADDRESS=temporal-nginx:7233 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + image: temporalio/server:${TEMPORAL_VERSION} + ports: + - published: 7232 + target: 7232 + - published: 8003 + target: 8003 + restart: on-failure + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + networks: + - temporal-network + + temporal-create-namespace: + <<: *loki-logging + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + - temporal-nginx + environment: + - TEMPORAL_ADDRESS=temporal-nginx:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-admin-tools: + <<: *loki-logging + container_name: temporal-admin-tools + depends_on: + - temporal-nginx + environment: + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + stdin_open: true + tty: true + networks: + - temporal-network + + temporal-ui: + container_name: temporal-ui + depends_on: + - temporal-nginx + environment: + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + - TEMPORAL_CLI_ADDRESS=temporal-nginx:7233 + - TEMPORAL_ADDRESS=temporal-nginx:7233 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + ports: + - 8080:8080 + networks: + - temporal-network + + prometheus: + container_name: prometheus + image: prom/prometheus:v2.37.0 + ports: + - published: 9090 + target: 9090 + volumes: + - type: bind + source: ./deployment/prometheus/config.yml + target: /etc/prometheus/prometheus.yml + depends_on: + - temporal-worker + networks: + - temporal-network + + grafana: + container_name: grafana + image: grafana/grafana:7.5.16 + build: './deployment/grafana' + environment: + - GF_AUTH_DISABLE_LOGIN_FORM=true + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + ports: + - published: 8085 + target: 3000 + volumes: + - type: bind + source: ./deployment/grafana/provisioning/datasources + target: /etc/grafana/provisioning/datasources + depends_on: + - prometheus + networks: + - temporal-network + + jaeger-all-in-one: + image: jaegertracing/all-in-one:1.37 + ports: + - published: 16686 + target: 16686 + - published: 14268 + target: 14268 + - published: 14250 + target: 14250 + networks: + - temporal-network + + otel-collector: + image: otel/opentelemetry-collector:0.47.0 + command: [ "--config=/etc/otel-collector-config.yaml" ] + volumes: + - type: bind + source: ./deployment/otel/otel-config.yaml + target: /etc/otel-collector-config.yaml + ports: + - published: 1888 + target: 1888 + - published: 13133 + target: 13133 + - published: 4317 + target: 4317 + - published: 55670 + target: 55670 + depends_on: + - jaeger-all-in-one + networks: + - temporal-network + + temporal-nginx: + <<: *loki-logging + image: nginx:1.22.1 + container_name: temporal-nginx + restart: unless-stopped + depends_on: + - temporal-frontend + - temporal-frontend2 + ports: + - 7233:7233 + volumes: + - ./deployment/nginx/nginx.conf:/etc/nginx/nginx.conf + networks: + - temporal-network + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-mysql-es.yml b/compose/docker-compose-mysql-es.yml new file mode 100644 index 0000000..fca2711 --- /dev/null +++ b/compose/docker-compose-mysql-es.yml @@ -0,0 +1,134 @@ +services: + mysql: + image: mysql:${MYSQL_VERSION} + container_name: temporal-mysql + ports: + - "3306:3306" + environment: + - MYSQL_ROOT_PASSWORD=root + networks: + - temporal-network + volumes: + - /var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + elasticsearch: + image: elasticsearch:${ELASTICSEARCH_VERSION} + container_name: temporal-elasticsearch + ports: + - "9200:9200" + environment: + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms256m -Xmx256m + - xpack.security.enabled=false + networks: + - temporal-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + mysql: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + - DB=mysql8 + - DB_PORT=3306 + - MYSQL_USER=root + - MYSQL_PWD=root + - MYSQL_SEEDS=mysql + - SQL_PASSWORD=root + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_SCHEME=http + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-mysql-es.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - DB=mysql8 + - DB_PORT=3306 + - MYSQL_USER=root + - MYSQL_PWD=root + - MYSQL_SEEDS=mysql + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-mysql.yml b/compose/docker-compose-mysql.yml new file mode 100644 index 0000000..0826a1b --- /dev/null +++ b/compose/docker-compose-mysql.yml @@ -0,0 +1,102 @@ +services: + mysql: + image: mysql:${MYSQL_VERSION} + container_name: temporal-mysql + ports: + - "3306:3306" + environment: + - MYSQL_ROOT_PASSWORD=root + networks: + - temporal-network + volumes: + - /var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + mysql: + condition: service_healthy + environment: + - DB=mysql8 + - DB_PORT=3306 + - MYSQL_USER=root + - MYSQL_PWD=root + - MYSQL_SEEDS=mysql + - SQL_PASSWORD=root + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-mysql.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - DB=mysql8 + - DB_PORT=3306 + - MYSQL_USER=root + - MYSQL_PWD=root + - MYSQL_SEEDS=mysql + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-postgres-opensearch.yml b/compose/docker-compose-postgres-opensearch.yml new file mode 100644 index 0000000..9a22a6a --- /dev/null +++ b/compose/docker-compose-postgres-opensearch.yml @@ -0,0 +1,141 @@ +services: + postgresql: + image: postgres:${POSTGRESQL_VERSION} + container_name: temporal-postgresql + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: temporal + POSTGRES_USER: temporal + networks: + - temporal-network + volumes: + - /var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U temporal"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + opensearch: + image: opensearchproject/opensearch:${OPENSEARCH_VERSION} + container_name: temporal-opensearch + ports: + - "9200:9200" + environment: + - discovery.type=single-node + - OPENSEARCH_JAVA_OPTS=-Xms256m -Xmx256m + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - plugins.security.disabled=true + ulimits: + nofile: + soft: 65536 + hard: 65536 + networks: + - temporal-network + volumes: + - /usr/share/opensearch/data + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + postgresql: + condition: service_healthy + opensearch: + condition: service_healthy + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - SQL_PASSWORD=temporal + - ES_HOST=opensearch + - ES_PORT=9200 + - ES_SCHEME=http + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-postgres-opensearch.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - ENABLE_ES=true + - ES_SEEDS=opensearch + - ES_VERSION=v7 + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-postgres.yml b/compose/docker-compose-postgres.yml new file mode 100644 index 0000000..7fc9ed0 --- /dev/null +++ b/compose/docker-compose-postgres.yml @@ -0,0 +1,103 @@ +services: + postgresql: + image: postgres:${POSTGRESQL_VERSION} + container_name: temporal-postgresql + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: temporal + POSTGRES_USER: temporal + networks: + - temporal-network + volumes: + - /var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U temporal"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + postgresql: + condition: service_healthy + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - SQL_PASSWORD=temporal + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-postgres.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/docker-compose-tls.yml b/compose/docker-compose-tls.yml new file mode 100644 index 0000000..ea8107b --- /dev/null +++ b/compose/docker-compose-tls.yml @@ -0,0 +1,202 @@ +services: + elasticsearch: + container_name: temporal-elasticsearch + environment: + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms256m -Xmx256m + - ELASTIC_PASSWORD=elastic + - xpack.security.enabled=true + - xpack.security.http.ssl.enabled=true + - xpack.security.http.ssl.key=certs/elasticsearch-key.pem + - xpack.security.http.ssl.certificate=certs/elasticsearch.pem + - xpack.security.http.ssl.certificate_authorities=certs/ca.pem + - xpack.security.transport.ssl.enabled=true + - xpack.security.transport.ssl.key=certs/elasticsearch-key.pem + - xpack.security.transport.ssl.certificate=certs/elasticsearch.pem + - xpack.security.transport.ssl.certificate_authorities=certs/ca.pem + image: elasticsearch:${ELASTICSEARCH_VERSION} + networks: + - temporal-network + expose: + - 9200 + volumes: + - temporal_tls_pki:/usr/share/elasticsearch/config/certs + - /var/lib/elasticsearch/data + restart: on-failure + healthcheck: + test: ["CMD-SHELL", "curl -f -k -u elastic:elastic https://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + postgresql: + container_name: temporal-postgresql + command: + - "-c" + - "ssl=on" + - "-c" + - "ssl_cert_file=/pki/postgresql.pem" + - "-c" + - "ssl_key_file=/pki/postgresql-key.pem" + - "-c" + - "ssl_ca_file=/pki/ca.pem" + environment: + POSTGRES_PASSWORD: temporal + POSTGRES_USER: temporal + image: postgres:${POSTGRESQL_VERSION} + networks: + - temporal-network + expose: + - 5432 + volumes: + - temporal_tls_pki:/pki + - /var/lib/postgresql/data + restart: on-failure + healthcheck: + test: ["CMD-SHELL", "pg_isready -U temporal"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools-setup: + container_name: temporal-admin-tools-setup + restart: on-failure:6 + depends_on: + postgresql: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - SQL_PASSWORD=temporal + - SQL_TLS=true + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_SCHEME=https + - ES_USER=elastic + - ES_PWD=elastic + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + build: + context: . + dockerfile: tls/Dockerfile.admin-tools-tls + args: + - BASEIMAGE=admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + image: temporalio/admin-tools-tls:${TEMPORAL_ADMINTOOLS_VERSION} + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-postgres-es-tls.sh + + temporal: + container_name: temporal + build: + context: . + dockerfile: tls/Dockerfile.auto-setup-tls + args: + - BASEIMAGE=server:${TEMPORAL_VERSION} + image: server-tls:${TEMPORAL_VERSION} + depends_on: + temporal-admin-tools-setup: + condition: service_completed_successfully + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - SQL_TLS=true + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - ES_SCHEME=https + - ES_USER=elastic + - ES_PWD=elastic + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CLI_ADDRESS=temporal:7233 + networks: + - temporal-network + ports: + - 7233:7233 + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + restart: on-failure + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools-tls:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-admin-tools: + container_name: temporal-admin-tools + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CLI_ADDRESS=temporal:7233 + build: + context: . + dockerfile: tls/Dockerfile.admin-tools-tls + args: + - BASEIMAGE=admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + image: temporalio/admin-tools-tls:${TEMPORAL_ADMINTOOLS_VERSION} + networks: + - temporal-network + stdin_open: true + tty: true + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + restart: on-failure + +networks: + temporal-network: + driver: bridge + name: temporal-network +volumes: + temporal_tls_pki: + external: true diff --git a/compose/docker-compose-validate-multirole.yml b/compose/docker-compose-validate-multirole.yml new file mode 100644 index 0000000..baa7cfc --- /dev/null +++ b/compose/docker-compose-validate-multirole.yml @@ -0,0 +1,23 @@ +services: + temporal-validate: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-validate + restart: on-failure:5 + depends_on: + temporal-create-namespace: + condition: service_completed_successfully + environment: + - TEMPORAL_ADDRESS=temporal-nginx:7233 + - NAMESPACE=default + - MAX_WAIT_TIME=300 + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh", "-c"] + command: ["exec /scripts/validate-temporal.sh"] + +networks: + temporal-network: + external: true + name: temporal-network diff --git a/compose/docker-compose-validate.yml b/compose/docker-compose-validate.yml new file mode 100644 index 0000000..2d0ea06 --- /dev/null +++ b/compose/docker-compose-validate.yml @@ -0,0 +1,23 @@ +services: + temporal-validate: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-validate + restart: on-failure:5 + depends_on: + temporal-create-namespace: + condition: service_completed_successfully + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - NAMESPACE=default + - MAX_WAIT_TIME=300 + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh", "-c"] + command: ["exec /scripts/validate-temporal.sh"] + +networks: + temporal-network: + external: true + name: temporal-network diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml new file mode 100644 index 0000000..5c2bd8d --- /dev/null +++ b/compose/docker-compose.yml @@ -0,0 +1,135 @@ +services: + postgresql: + image: postgres:${POSTGRESQL_VERSION} + container_name: temporal-postgresql + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: temporal + POSTGRES_USER: temporal + networks: + - temporal-network + volumes: + - /var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U temporal"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + elasticsearch: + image: elasticsearch:${ELASTICSEARCH_VERSION} + container_name: temporal-elasticsearch + ports: + - "9200:9200" + environment: + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=512mb + - cluster.routing.allocation.disk.watermark.high=256mb + - cluster.routing.allocation.disk.watermark.flood_stage=128mb + - discovery.type=single-node + - ES_JAVA_OPTS=-Xms256m -Xmx256m + - xpack.security.enabled=false + networks: + - temporal-network + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=1s || exit 1"] + interval: 5s + timeout: 5s + retries: 60 + start_period: 30s + + temporal-admin-tools: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-admin-tools + restart: on-failure:6 + depends_on: + postgresql: + condition: service_healthy + elasticsearch: + condition: service_healthy + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - SQL_PASSWORD=temporal + - ES_HOST=elasticsearch + - ES_PORT=9200 + - ES_SCHEME=http + - ES_VERSION=v7 + - ES_VISIBILITY_INDEX=temporal_visibility_v1_dev + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/setup-postgres-es.sh + + temporal: + image: temporalio/server:${TEMPORAL_VERSION} + container_name: temporal + depends_on: + temporal-admin-tools: + condition: service_completed_successfully + environment: + - DB=postgres12 + - DB_PORT=5432 + - POSTGRES_USER=temporal + - POSTGRES_PWD=temporal + - POSTGRES_SEEDS=postgresql + - ENABLE_ES=true + - ES_SEEDS=elasticsearch + - ES_VERSION=v7 + - BIND_ON_IP=0.0.0.0 + - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml + networks: + - temporal-network + ports: + - '7233:7233' + volumes: + - ./dynamicconfig:/etc/temporal/config/dynamicconfig + healthcheck: + test: ["CMD", "nc", "-z", "localhost", "7233"] + interval: 5s + timeout: 3s + start_period: 30s + retries: 60 + + temporal-create-namespace: + image: temporalio/admin-tools:${TEMPORAL_ADMINTOOLS_VERSION} + container_name: temporal-create-namespace + restart: on-failure:5 + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - DEFAULT_NAMESPACE=default + networks: + - temporal-network + volumes: + - ./scripts:/scripts + entrypoint: ["/bin/sh"] + command: /scripts/create-namespace.sh + + temporal-ui: + container_name: temporal-ui + depends_on: + temporal: + condition: service_healthy + environment: + - TEMPORAL_ADDRESS=temporal:7233 + - TEMPORAL_CORS_ORIGINS=http://localhost:3000 + image: temporalio/ui:${TEMPORAL_UI_VERSION} + networks: + - temporal-network + ports: + - 8080:8080 + +networks: + temporal-network: + driver: bridge + name: temporal-network diff --git a/compose/dynamicconfig/README.md b/compose/dynamicconfig/README.md new file mode 100644 index 0000000..85a37c0 --- /dev/null +++ b/compose/dynamicconfig/README.md @@ -0,0 +1,39 @@ +Use `docker.yaml` file to override the default dynamic config value (they are specified +when creating the service config). + +Each key can have zero or more values and each value can have zero or more +constraints. There are only three types of constraint: +1. `namespace`: `string` +2. `taskQueueName`: `string` +3. `taskType`: `int` (`1`:`Workflow`, `2`:`Activity`) +A value will be selected and returned if all its has exactly the same constraints +as the ones specified in query filters (including the number of constraints). + +Please use the following format: +``` +testGetBoolPropertyKey: + - value: false + - value: true + constraints: + namespace: "global-samples-namespace" + - value: false + constraints: + namespace: "samples-namespace" +testGetDurationPropertyKey: + - value: "1m" + constraints: + namespace: "samples-namespace" + taskQueueName: "longIdleTimeTaskqueue" +testGetFloat64PropertyKey: + - value: 12.0 + constraints: + namespace: "samples-namespace" +testGetMapPropertyKey: + - value: + key1: 1 + key2: "value 2" + key3: + - false + - key4: true + key5: 2.0 +``` diff --git a/compose/dynamicconfig/development-cass.yaml b/compose/dynamicconfig/development-cass.yaml new file mode 100644 index 0000000..4b91616 --- /dev/null +++ b/compose/dynamicconfig/development-cass.yaml @@ -0,0 +1,3 @@ +system.forceSearchAttributesCacheRefreshOnRead: + - value: true # Dev setup only. Please don't turn this on in production. + constraints: {} diff --git a/compose/dynamicconfig/development-sql.yaml b/compose/dynamicconfig/development-sql.yaml new file mode 100644 index 0000000..8862dfa --- /dev/null +++ b/compose/dynamicconfig/development-sql.yaml @@ -0,0 +1,6 @@ +limit.maxIDLength: + - value: 255 + constraints: {} +system.forceSearchAttributesCacheRefreshOnRead: + - value: true # Dev setup only. Please don't turn this on in production. + constraints: {} diff --git a/compose/dynamicconfig/docker.yaml b/compose/dynamicconfig/docker.yaml new file mode 100644 index 0000000..e69de29 diff --git a/compose/scripts/create-namespace.sh b/compose/scripts/create-namespace.sh new file mode 100755 index 0000000..45334f0 --- /dev/null +++ b/compose/scripts/create-namespace.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -eu + +NAMESPACE=${DEFAULT_NAMESPACE:-default} +TEMPORAL_ADDRESS=${TEMPORAL_ADDRESS:-temporal:7233} + +echo "Waiting for Temporal server port to be available..." +nc -z -w 10 $(echo $TEMPORAL_ADDRESS | cut -d: -f1) $(echo $TEMPORAL_ADDRESS | cut -d: -f2) +echo 'Temporal server port is available' + +echo 'Waiting for Temporal server to be healthy...' +max_attempts=3 +attempt=0 + +until temporal operator cluster health --address $TEMPORAL_ADDRESS; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "Server did not become healthy after $max_attempts attempts" + exit 1 + fi + echo "Server not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 5 +done + +echo "Server is healthy, creating namespace '$NAMESPACE'..." +temporal operator namespace describe -n $NAMESPACE --address $TEMPORAL_ADDRESS || temporal operator namespace create -n $NAMESPACE --address $TEMPORAL_ADDRESS +echo "Namespace '$NAMESPACE' created" diff --git a/compose/scripts/setup-cassandra-es.sh b/compose/scripts/setup-cassandra-es.sh new file mode 100755 index 0000000..42fce55 --- /dev/null +++ b/compose/scripts/setup-cassandra-es.sh @@ -0,0 +1,60 @@ +#!/bin/sh +set -eu + +# Validate required environment variables +: "${ES_SCHEME:?ERROR: ES_SCHEME environment variable is required}" +: "${ES_HOST:?ERROR: ES_HOST environment variable is required}" +: "${ES_PORT:?ERROR: ES_PORT environment variable is required}" +: "${ES_VISIBILITY_INDEX:?ERROR: ES_VISIBILITY_INDEX environment variable is required}" +: "${ES_VERSION:?ERROR: ES_VERSION environment variable is required}" + +echo 'Starting Cassandra and Elasticsearch schema setup...' +echo 'Waiting for Cassandra port to be available...' +nc -z -w 10 cassandra 9042 +echo 'Cassandra port is available' +echo 'Waiting for Cassandra to be ready...' +until temporal-cassandra-tool --ep cassandra validate-health; do + echo 'Cassandra not ready yet, waiting...' + sleep 2 +done +echo 'Cassandra is ready' + +# Create and setup Cassandra keyspace +temporal-cassandra-tool --ep cassandra create -k temporal --rf 1 +temporal-cassandra-tool --ep cassandra -k temporal setup-schema -v 0.0 +temporal-cassandra-tool --ep cassandra -k temporal update-schema -d /etc/temporal/schema/cassandra/temporal/versioned + +# Setup Elasticsearch index +# temporal-elasticsearch-tool is available in v1.30+ server releases +if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo 'Using temporal-elasticsearch-tool for Elasticsearch setup' + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" setup-schema + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" create-index --index $ES_VISIBILITY_INDEX +else + echo 'Using curl for Elasticsearch setup' + echo 'WARNING: curl will be removed from admin-tools in v1.30.' + echo 'Waiting for Elasticsearch to be ready...' + max_attempts=30 + attempt=0 + until curl -s -f "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s"; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "ERROR: Elasticsearch did not become ready after $max_attempts attempts" + echo "Last error from curl:" + curl "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s" 2>&1 || true + exit 1 + fi + echo "Elasticsearch not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo '' + echo 'Elasticsearch is ready' + echo 'Creating index template...' + curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" -H 'Content-Type: application/json' --data-binary "@/etc/temporal/schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + echo '' + echo 'Creating index...' + curl --head --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>/dev/null || curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + echo '' +fi + +echo 'Cassandra and Elasticsearch setup complete' diff --git a/compose/scripts/setup-mysql-es.sh b/compose/scripts/setup-mysql-es.sh new file mode 100755 index 0000000..408df35 --- /dev/null +++ b/compose/scripts/setup-mysql-es.sh @@ -0,0 +1,54 @@ +#!/bin/sh +set -eu + +# Validate required environment variables +: "${ES_SCHEME:?ERROR: ES_SCHEME environment variable is required}" +: "${ES_HOST:?ERROR: ES_HOST environment variable is required}" +: "${ES_PORT:?ERROR: ES_PORT environment variable is required}" +: "${ES_VISIBILITY_INDEX:?ERROR: ES_VISIBILITY_INDEX environment variable is required}" +: "${ES_VERSION:?ERROR: ES_VERSION environment variable is required}" + +echo 'Starting MySQL and Elasticsearch schema setup...' +echo 'Waiting for MySQL port to be available...' +nc -z -w 10 mysql 3306 +echo 'MySQL port is available' + +# Create and setup temporal database +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal create +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal setup-schema -v 0.0 +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal update-schema -d /etc/temporal/schema/mysql/v8/temporal/versioned + +# Setup Elasticsearch index +# temporal-elasticsearch-tool is available in v1.30+ server releases +if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo 'Using temporal-elasticsearch-tool for Elasticsearch setup' + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" setup-schema + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" create-index --index $ES_VISIBILITY_INDEX +else + echo 'Using curl for Elasticsearch setup' + echo 'WARNING: curl will be removed from admin-tools in v1.30.' + echo 'Waiting for Elasticsearch to be ready...' + max_attempts=30 + attempt=0 + until curl -s -f "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s"; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "ERROR: Elasticsearch did not become ready after $max_attempts attempts" + echo "Last error from curl:" + curl "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s" 2>&1 || true + exit 1 + fi + echo "Elasticsearch not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo '' + echo 'Elasticsearch is ready' + echo 'Creating index template...' + curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" -H 'Content-Type: application/json' --data-binary "@/etc/temporal/schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + echo '' + echo 'Creating index...' + curl --head --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>/dev/null || curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + echo '' +fi + +echo 'MySQL and Elasticsearch setup complete' diff --git a/compose/scripts/setup-mysql.sh b/compose/scripts/setup-mysql.sh new file mode 100755 index 0000000..943c1d4 --- /dev/null +++ b/compose/scripts/setup-mysql.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +echo 'Starting MySQL schema setup...' +echo 'Waiting for MySQL port to be available...' +nc -z -w 10 mysql 3306 +echo 'MySQL port is available' + +# Create and setup temporal database +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal create +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal setup-schema -v 0.0 +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal update-schema -d /etc/temporal/schema/mysql/v8/temporal/versioned + +# Create and setup visibility database +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal_visibility create +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal_visibility setup-schema -v 0.0 +temporal-sql-tool --plugin mysql8 --ep mysql -u root -p 3306 --db temporal_visibility update-schema -d /etc/temporal/schema/mysql/v8/visibility/versioned + +echo 'MySQL schema setup complete' diff --git a/compose/scripts/setup-postgres-es-tls.sh b/compose/scripts/setup-postgres-es-tls.sh new file mode 100755 index 0000000..5b77c60 --- /dev/null +++ b/compose/scripts/setup-postgres-es-tls.sh @@ -0,0 +1,57 @@ +#!/bin/sh +set -eu + +# Validate required environment variables +: "${ES_SCHEME:?ERROR: ES_SCHEME environment variable is required}" +: "${ES_HOST:?ERROR: ES_HOST environment variable is required}" +: "${ES_PORT:?ERROR: ES_PORT environment variable is required}" +: "${ES_VISIBILITY_INDEX:?ERROR: ES_VISIBILITY_INDEX environment variable is required}" +: "${ES_VERSION:?ERROR: ES_VERSION environment variable is required}" +: "${ES_USER:?ERROR: ES_USER environment variable is required}" +: "${ES_PWD:?ERROR: ES_PWD environment variable is required}" +: "${POSTGRES_USER:?ERROR: POSTGRES_USER environment variable is required}" + +echo 'Starting PostgreSQL and Elasticsearch (TLS) schema setup...' +echo 'Waiting for PostgreSQL port to be available...' +nc -z -w 10 postgresql ${POSTGRES_DEFAULT_PORT:-5432} +echo 'PostgreSQL port is available' + +# Create and setup temporal database with TLS +temporal-sql-tool --plugin postgres12 --ep postgresql -u ${POSTGRES_USER} -p ${POSTGRES_DEFAULT_PORT:-5432} --db temporal --tls --tls-ca-file /usr/local/share/ca-certificates/ca.crt create +temporal-sql-tool --plugin postgres12 --ep postgresql -u ${POSTGRES_USER} -p ${POSTGRES_DEFAULT_PORT:-5432} --db temporal --tls --tls-ca-file /usr/local/share/ca-certificates/ca.crt setup-schema -v 0.0 +temporal-sql-tool --plugin postgres12 --ep postgresql -u ${POSTGRES_USER} -p ${POSTGRES_DEFAULT_PORT:-5432} --db temporal --tls --tls-ca-file /usr/local/share/ca-certificates/ca.crt update-schema -d /etc/temporal/schema/postgresql/v12/temporal/versioned + +# Setup Elasticsearch index with TLS +# temporal-elasticsearch-tool is available in v1.30+ server releases +if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo 'Using temporal-elasticsearch-tool for Elasticsearch setup' + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" --user "$ES_USER" --password "$ES_PWD" setup-schema + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" --user "$ES_USER" --password "$ES_PWD" create-index --index $ES_VISIBILITY_INDEX +else + echo 'Using curl for Elasticsearch setup' + echo 'WARNING: curl will be removed from admin-tools in v1.30.' + echo 'Waiting for Elasticsearch to be ready...' + max_attempts=30 + attempt=0 + until curl -s -f -k -u "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s"; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "ERROR: Elasticsearch did not become ready after $max_attempts attempts" + echo "Last error from curl:" + curl -k -u "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s" 2>&1 || true + exit 1 + fi + echo "Elasticsearch not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo '' + echo 'Elasticsearch is ready' + echo 'Creating index template...' + curl -X PUT --fail -k -u "$ES_USER:$ES_PWD" "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" -H 'Content-Type: application/json' --data-binary "@/etc/temporal/schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + echo '' + echo 'Creating index...' + curl -k -u "$ES_USER:$ES_PWD" --head --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>/dev/null || curl -k -u "$ES_USER:$ES_PWD" -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + echo '' +fi + +echo 'PostgreSQL and Elasticsearch (TLS) setup complete' diff --git a/compose/scripts/setup-postgres-es.sh b/compose/scripts/setup-postgres-es.sh new file mode 100755 index 0000000..ded7e32 --- /dev/null +++ b/compose/scripts/setup-postgres-es.sh @@ -0,0 +1,54 @@ +#!/bin/sh +set -eu + +# Validate required environment variables +: "${ES_SCHEME:?ERROR: ES_SCHEME environment variable is required}" +: "${ES_HOST:?ERROR: ES_HOST environment variable is required}" +: "${ES_PORT:?ERROR: ES_PORT environment variable is required}" +: "${ES_VISIBILITY_INDEX:?ERROR: ES_VISIBILITY_INDEX environment variable is required}" +: "${ES_VERSION:?ERROR: ES_VERSION environment variable is required}" + +echo 'Starting PostgreSQL and Elasticsearch schema setup...' +echo 'Waiting for PostgreSQL port to be available...' +nc -z -w 10 postgresql 5432 +echo 'PostgreSQL port is available' + +# Create and setup temporal database +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal create +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal setup-schema -v 0.0 +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal update-schema -d /etc/temporal/schema/postgresql/v12/temporal/versioned + +# Setup Elasticsearch index +# temporal-elasticsearch-tool is available in v1.30+ server releases +if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo 'Using temporal-elasticsearch-tool for Elasticsearch setup' + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" setup-schema + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" create-index --index $ES_VISIBILITY_INDEX +else + echo 'Using curl for Elasticsearch setup' + echo 'WARNING: curl will be removed from admin-tools in v1.30.' + echo 'Waiting for Elasticsearch to be ready...' + max_attempts=30 + attempt=0 + until curl -s -f "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s"; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "ERROR: Elasticsearch did not become ready after $max_attempts attempts" + echo "Last error from curl:" + curl "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s" 2>&1 || true + exit 1 + fi + echo "Elasticsearch not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo '' + echo 'Elasticsearch is ready' + echo 'Creating index template...' + curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" -H 'Content-Type: application/json' --data-binary "@/etc/temporal/schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + echo '' + echo 'Creating index...' + curl --head --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>/dev/null || curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + echo '' +fi + +echo 'PostgreSQL and Elasticsearch setup complete' diff --git a/compose/scripts/setup-postgres-opensearch.sh b/compose/scripts/setup-postgres-opensearch.sh new file mode 100755 index 0000000..6aa7466 --- /dev/null +++ b/compose/scripts/setup-postgres-opensearch.sh @@ -0,0 +1,54 @@ +#!/bin/sh +set -eu + +# Validate required environment variables +: "${ES_SCHEME:?ERROR: ES_SCHEME environment variable is required}" +: "${ES_HOST:?ERROR: ES_HOST environment variable is required}" +: "${ES_PORT:?ERROR: ES_PORT environment variable is required}" +: "${ES_VISIBILITY_INDEX:?ERROR: ES_VISIBILITY_INDEX environment variable is required}" +: "${ES_VERSION:?ERROR: ES_VERSION environment variable is required}" + +echo 'Starting PostgreSQL and OpenSearch schema setup...' +echo 'Waiting for PostgreSQL port to be available...' +nc -z -w 10 postgresql 5432 +echo 'PostgreSQL port is available' + +# Create and setup temporal database +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal create +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal setup-schema -v 0.0 +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal update-schema -d /etc/temporal/schema/postgresql/v12/temporal/versioned + +# Setup OpenSearch index +# temporal-elasticsearch-tool is available in v1.30+ server releases +if [ -x /usr/local/bin/temporal-elasticsearch-tool ]; then + echo 'Using temporal-elasticsearch-tool for OpenSearch setup' + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" setup-schema + temporal-elasticsearch-tool --ep "$ES_SCHEME://$ES_HOST:$ES_PORT" create-index --index $ES_VISIBILITY_INDEX +else + echo 'Using curl for OpenSearch setup' + echo 'WARNING: curl will be removed from admin-tools in v1.30.' + echo 'Waiting for OpenSearch to be ready...' + max_attempts=30 + attempt=0 + until curl -s -f "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s"; do + attempt=$((attempt + 1)) + if [ $attempt -ge $max_attempts ]; then + echo "ERROR: OpenSearch did not become ready after $max_attempts attempts" + echo "Last error from curl:" + curl "$ES_SCHEME://$ES_HOST:$ES_PORT/_cluster/health?wait_for_status=yellow&timeout=1s" 2>&1 || true + exit 1 + fi + echo "OpenSearch not ready yet, waiting... (attempt $attempt/$max_attempts)" + sleep 2 + done + echo '' + echo 'OpenSearch is ready' + echo 'Creating index template...' + curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/_template/temporal_visibility_v1_template" -H 'Content-Type: application/json' --data-binary "@/etc/temporal/schema/elasticsearch/visibility/index_template_$ES_VERSION.json" + echo '' + echo 'Creating index...' + curl --head --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" 2>/dev/null || curl -X PUT --fail "$ES_SCHEME://$ES_HOST:$ES_PORT/$ES_VISIBILITY_INDEX" + echo '' +fi + +echo 'PostgreSQL and OpenSearch setup complete' diff --git a/compose/scripts/setup-postgres.sh b/compose/scripts/setup-postgres.sh new file mode 100755 index 0000000..8d99ccd --- /dev/null +++ b/compose/scripts/setup-postgres.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +echo 'Starting PostgreSQL schema setup...' +echo 'Waiting for PostgreSQL port to be available...' +nc -z -w 10 postgresql 5432 +echo 'PostgreSQL port is available' + +# Create and setup temporal database +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal create +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal setup-schema -v 0.0 +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal update-schema -d /etc/temporal/schema/postgresql/v12/temporal/versioned + +# Create and setup visibility database +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal_visibility create +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal_visibility setup-schema -v 0.0 +temporal-sql-tool --plugin postgres12 --ep postgresql -u temporal -p 5432 --db temporal_visibility update-schema -d /etc/temporal/schema/postgresql/v12/visibility/versioned + +echo 'PostgreSQL schema setup complete' diff --git a/compose/scripts/validate-temporal.sh b/compose/scripts/validate-temporal.sh new file mode 100755 index 0000000..09a31b2 --- /dev/null +++ b/compose/scripts/validate-temporal.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +set -e + +# Configuration +TEMPORAL_ADDRESS="${TEMPORAL_ADDRESS:-temporal:7233}" +NAMESPACE="${NAMESPACE:-default}" +MAX_WAIT_TIME="${MAX_WAIT_TIME:-300}" + +echo "=== Temporal Validation Script ===" +echo "Temporal address: $TEMPORAL_ADDRESS" +echo "Namespace: $NAMESPACE" +echo "Max wait time: ${MAX_WAIT_TIME}s" +echo + +# Wait a bit for Temporal to be ready +echo "Waiting for Temporal server to be accessible..." +sleep 15 + +# Check cluster health +echo "=== Checking cluster health ===" +if OUTPUT=$(temporal operator cluster health --address "$TEMPORAL_ADDRESS" 2>&1); then + echo "✓ Cluster health check passed" + echo "$OUTPUT" +else + echo "✗ Cluster health check failed" >&2 + echo "Error output:" >&2 + echo "$OUTPUT" >&2 + exit 1 +fi + +# Describe namespace to verify it exists and is accessible +echo +echo "=== Verifying namespace '$NAMESPACE' ===" +if OUTPUT=$(temporal operator namespace describe --namespace "$NAMESPACE" --address "$TEMPORAL_ADDRESS" 2>&1); then + echo "✓ Namespace '$NAMESPACE' is accessible" +else + echo "✗ Namespace '$NAMESPACE' not found or not accessible" >&2 + echo "Error output:" >&2 + echo "$OUTPUT" >&2 + exit 1 +fi + +# Try to start a simple workflow to validate full functionality +echo +echo "=== Testing workflow execution ===" +WORKFLOW_ID="validation-test-$(date +%s)" +TASK_QUEUE="validation-queue" + +# Start a workflow (this will fail gracefully if no workers, but proves the system is working) +if OUTPUT=$(temporal workflow start \ + --workflow-id "$WORKFLOW_ID" \ + --type "NonExistentWorkflow" \ + --task-queue "$TASK_QUEUE" \ + --namespace "$NAMESPACE" \ + --address "$TEMPORAL_ADDRESS" \ + --execution-timeout 10s 2>&1); then + echo "✓ Successfully initiated workflow (proves Temporal is functional)" + echo "$OUTPUT" + + # Clean up - terminate the workflow since it won't complete + echo "Terminating test workflow..." + temporal workflow terminate \ + --workflow-id "$WORKFLOW_ID" \ + --namespace "$NAMESPACE" \ + --address "$TEMPORAL_ADDRESS" \ + --reason "Validation complete" || true +else + # Workflow start failed, but check if workflow was actually created (means server is working) + echo "Workflow start command returned non-zero, checking if workflow exists..." + echo "Workflow start output:" + echo "$OUTPUT" + + if DESCRIBE_OUTPUT=$(temporal workflow describe \ + --workflow-id "$WORKFLOW_ID" \ + --namespace "$NAMESPACE" \ + --address "$TEMPORAL_ADDRESS" 2>&1); then + echo "✓ Workflow was created and server is functional" + echo "Terminating test workflow..." + temporal workflow terminate \ + --workflow-id "$WORKFLOW_ID" \ + --namespace "$NAMESPACE" \ + --address "$TEMPORAL_ADDRESS" \ + --reason "Validation complete" || true + else + echo "✗ Failed to create workflow" >&2 + echo "Workflow describe output:" >&2 + echo "$DESCRIBE_OUTPUT" >&2 + exit 1 + fi +fi + +echo +echo "=== All validation checks passed! ===" +exit 0 diff --git a/compose/tls/Dockerfile.admin-tools-tls b/compose/tls/Dockerfile.admin-tools-tls new file mode 100644 index 0000000..f3d8b45 --- /dev/null +++ b/compose/tls/Dockerfile.admin-tools-tls @@ -0,0 +1,9 @@ +ARG BASEIMAGE +FROM temporalio/${BASEIMAGE} + +USER root +COPY ./.pki/ca.pem /usr/local/share/ca-certificates/ca.crt + +RUN update-ca-certificates + +USER temporal diff --git a/compose/tls/Dockerfile.auto-setup-tls b/compose/tls/Dockerfile.auto-setup-tls new file mode 100644 index 0000000..f3d8b45 --- /dev/null +++ b/compose/tls/Dockerfile.auto-setup-tls @@ -0,0 +1,9 @@ +ARG BASEIMAGE +FROM temporalio/${BASEIMAGE} + +USER root +COPY ./.pki/ca.pem /usr/local/share/ca-certificates/ca.crt + +RUN update-ca-certificates + +USER temporal diff --git a/compose/tls/Dockerfile.tls b/compose/tls/Dockerfile.tls new file mode 100644 index 0000000..4b6aa22 --- /dev/null +++ b/compose/tls/Dockerfile.tls @@ -0,0 +1,24 @@ +# syntax=docker/dockerfile:1.3-labs + +FROM golang + +RUN go install github.com/cloudflare/cfssl/cmd/cfssl@latest +RUN go install github.com/cloudflare/cfssl/cmd/cfssljson@latest + +VOLUME ["/pki"] +WORKDIR /pki + +VOLUME ["/pki-out"] + +RUN < ca-config.json + echo '{"CN":"postgresql","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="127.0.0.1,localhost,postgresql" - | cfssljson -bare postgresql + echo '{"CN":"elasticsearch","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="127.0.0.1,localhost,elasticsearch" - | cfssljson -bare elasticsearch + + chgrp 999 postgresql-key.pem + chmod 640 postgresql-key.pem + chmod 640 elasticsearch-key.pem +EOF + +ENTRYPOINT cp /pki/ca.pem /pki-out/ca.pem diff --git a/compose/tls/README.md b/compose/tls/README.md new file mode 100644 index 0000000..bcb9f3e --- /dev/null +++ b/compose/tls/README.md @@ -0,0 +1,28 @@ +# Temporal with tls enabled dependencies + +## Execute + +run from a shell + +`./tls/run-tls.sh` + +## Script source with comments +```bash +#!/usr/bin/env bash +set -xe + +# Build container image for generating cert material +docker build -t temporal_tls:test -f ${PWD}/tls/Dockerfile.tls . +mkdir -p .pki + +# Run container to name volume and copy out CA certificate +docker run --rm -v temporal_tls_pki:/pki -v ${PWD}/.pki:/pki-out temporal_tls:test + +# Build extra layers which copy in CA certificate to local trust store +# Allows for not having to disable host verification on TLS connections +COMPOSE_PROJECT_NAME=tls_test docker-compose -f docker-compose-tls.yml build --no-cache + +# Run example docker-compose environment with elasticsearch and postgresql protected with TLS +COMPOSE_PROJECT_NAME=tls_test docker-compose -f docker-compose-tls.yml up + +``` diff --git a/compose/tls/run-tls.sh b/compose/tls/run-tls.sh new file mode 100755 index 0000000..0d1ef01 --- /dev/null +++ b/compose/tls/run-tls.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -xe + +# Build container image for generating cert material +DOCKER_BUILDKIT=1 docker build -t temporal_tls:test -f ${PWD}/tls/Dockerfile.tls . +mkdir -p .pki + +# Run container to name volume and copy out CA certificate +docker run --rm -v temporal_tls_pki:/pki -v ${PWD}/.pki:/pki-out temporal_tls:test + +# Build extra layers which copy in CA certificate to local trust store +# Allows for not having to disable host verification on TLS connections +COMPOSE_PROJECT_NAME=tls_test docker-compose -f docker-compose-tls.yml build --no-cache + +# Run example docker-compose environment with elasticsearch and postgresql protected with TLS +COMPOSE_PROJECT_NAME=tls_test docker-compose -f docker-compose-tls.yml up diff --git a/tls/tls-full/docker-compose.yml b/tls/tls-full/docker-compose.yml index 2e9aff0..255b716 100644 --- a/tls/tls-full/docker-compose.yml +++ b/tls/tls-full/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.5' - services: cassandra: image: cassandra:3.11 diff --git a/tls/tls-simple/docker-compose.yml b/tls/tls-simple/docker-compose.yml index 8589c2c..e33dc69 100644 --- a/tls/tls-simple/docker-compose.yml +++ b/tls/tls-simple/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.5' - services: cassandra: image: cassandra:3.11 From 4ff63a958d9fc56772b89438c597a3720b2b2832 Mon Sep 17 00:00:00 2001 From: "alex.stanfield" <13949480+chaptersix@users.noreply.github.com> Date: Wed, 17 Dec 2025 09:48:09 -0600 Subject: [PATCH 2/3] rm cert. (auto gen no leaks) --- compose/.pki/ca.pem | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 compose/.pki/ca.pem diff --git a/compose/.pki/ca.pem b/compose/.pki/ca.pem deleted file mode 100644 index 0c3da5d..0000000 --- a/compose/.pki/ca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC6jCCAdKgAwIBAgIUcE+9Bob3MuRpMzBXMExXFztYvV8wDQYJKoZIhvcNAQEL -BQAwDTELMAkGA1UEAxMCQ0EwHhcNMjUxMjE2MTgwMjAwWhcNMzAxMjE1MTgwMjAw -WjANMQswCQYDVQQDEwJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AM9VopN8jDN7AR1mY96FMtWVrlKCEQoXdxxb1wqyDAar1rrH5svtOTBvmwo00v+v -I8i1Ord1u2p54sW2a4MdEaEaQwpDbCRDOl285/H8xsSXQGskbTIuqAnQXv00+Pld -UptDK28P6E/1BCmhiSju4olrgzlSzN124MKoSeJ36TJ+gToLRMNey8RV4HgVVlZa -pmXa+SLwn8ssBM14yYyuj1wxtVEp15DSIwXlet2Du0+AIMsSK5rxd/GDl6nrvQt6 -TwL0MYV1FoVwMtV8SDpmy7u2CsgvbTcCxBvr3pwSUh+6r10K5wfDtMTZ4eIaI8jg -0T9SGJZW3oOoUgjANnJ/McMCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMyu2ChnE9nDq46qxFtHOkfdUFK+MA0GCSqG -SIb3DQEBCwUAA4IBAQCNzqimKll1I23xRgr1Cqe008W3fTiM1g4Z+7kpt/kYzseE -obkzswWeNSEHHgBwMvHHTkLm7ftMZ+FLsNC/DNb3uSVu6oUcTzW461QTzrz9t02s -1w8ZfMrqsAWHPHEN5/ESGwSYO7cW7ISEkD3PHppX7mxHw38u589TvBBXtjXqx6Zv -p4bInVjRyL7qf/Byw8SDJXNSWfjEhQOAN2NuMmjMuXJaEVMf6eh95EfVO6KhArD9 -rJ97OqnTQWsJO3NOAVd2R4nxcgi6/3XZRkISf33XwXMUyIlw2rxzXFv/WSgMVFCl -Mc41TvvkexS1NTMJmj2hn7j9U/w4NhNoI/G3t7zm ------END CERTIFICATE----- From 90d78aff25a0c59c55eab72cc1112a7f725865da Mon Sep 17 00:00:00 2001 From: "alex.stanfield" <13949480+chaptersix@users.noreply.github.com> Date: Mon, 5 Jan 2026 12:02:29 -0600 Subject: [PATCH 3/3] auto bump --- .github/workflows/release.yaml | 154 +++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..8c51456 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,154 @@ +name: Create a release + +on: + workflow_dispatch: + inputs: + tag: + description: "Tag for new version (1.23.4)" + required: true + admintools_tag: + description: "Admin tools version (1.23.4-tctl-1.0-cli-1.0)" + required: true + +permissions: + contents: write + pull-requests: write + +jobs: + create-release: + name: Create a release + runs-on: ubuntu-latest + timeout-minutes: 20 + + defaults: + run: + shell: bash + + steps: + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.TEMPORAL_CICD_APP_ID }} + private-key: ${{ secrets.TEMPORAL_CICD_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@v6 + with: + persist-credentials: true + token: ${{ steps.generate_token.outputs.token }} + fetch-depth: 0 + fetch-tags: true + + - name: Set up Github credentials + run: | + git config --local user.name 'Temporal Data' + git config --local user.email 'commander-data@temporal.io' + + - name: Update images version and create PR + id: create_pr + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + TAG: ${{ github.event.inputs.tag }} + ADMINTOOLS_TAG: ${{ github.event.inputs.admintools_tag }} + run: | + sed -i -e "s/^TEMPORAL_VERSION=.*$/TEMPORAL_VERSION=$TAG/g" compose/.env + sed -i -e "s/^TEMPORAL_ADMINTOOLS_VERSION=.*$/TEMPORAL_ADMINTOOLS_VERSION=$ADMINTOOLS_TAG/g" compose/.env + + if [ -z "$(git diff --stat)" ]; then + echo "No changes to commit" + echo "SKIPPED=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + + BRANCH="release/v${TAG}" + git checkout -b "$BRANCH" + git add . + git commit -m "Bump Server version to $TAG" + git push origin "$BRANCH" + + gh repo set-default ${{ github.repository }} + PR_URL=$(gh pr create \ + --title "Bump Server version to $TAG" \ + --body "Automated version bump for release v${TAG}" \ + --base main \ + --head "$BRANCH") + echo "PR_URL=$PR_URL" >> "$GITHUB_OUTPUT" + + - name: Auto-merge PR + if: steps.create_pr.outputs.SKIPPED != 'true' + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + PR_URL: ${{ steps.create_pr.outputs.PR_URL }} + run: | + gh pr merge "$PR_URL" --auto --squash --delete-branch + + - name: Wait for PR to merge + if: steps.create_pr.outputs.SKIPPED != 'true' + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + PR_URL: ${{ steps.create_pr.outputs.PR_URL }} + run: | + echo "Waiting for PR to merge (checks may take ~10 minutes)..." + for _ in {1..90}; do + STATE=$(gh pr view "$PR_URL" --json state --jq '.state') + if [ "$STATE" = "MERGED" ]; then + echo "PR merged successfully" + exit 0 + elif [ "$STATE" = "CLOSED" ]; then + echo "::error::PR was closed without merging" + exit 1 + fi + echo "PR state: $STATE, waiting..." + sleep 10 + done + echo "::error::Timed out waiting for PR to merge" + exit 1 + + - name: Checkout main after merge + if: steps.create_pr.outputs.SKIPPED != 'true' + run: | + git fetch origin main + git checkout main + git pull origin main + + - name: Create and push tag + env: + TAG: 'v${{ github.event.inputs.tag }}' + run: | + if [ -z "$(git tag -l "$TAG")" ]; then + git tag "$TAG" + git push origin "$TAG" + elif [ "$(git rev-list -n 1 "$TAG")" != "$(git rev-parse HEAD)" ]; then + echo "::error::Tag already exists and it doesn't reference current HEAD of main branch" + exit 1 + fi + + - name: Create draft release + id: release_notes + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + TAG: 'v${{ github.event.inputs.tag }}' + run: | + TEMPFILE=$(mktemp) + cat > "$TEMPFILE" <<- EOF + # Release Highlights + Please check [main repo](https://github.com/temporalio/temporal/releases/tag/${TAG}) release notes. + EOF + + gh repo set-default ${{ github.repository }} + RELEASE_URL=$(gh release create "$TAG" --verify-tag --draft --title "$TAG" -F "$TEMPFILE") + echo "RELEASE_URL=$RELEASE_URL" >> "$GITHUB_OUTPUT" + + - name: Create summary + env: + PR_URL: ${{ steps.create_pr.outputs.PR_URL }} + run: | + TEMPFILE=$(mktemp) + cat > "$TEMPFILE" <<- EOF + # Job summary + PR: ${PR_URL:-"No changes needed"} + Draft release: ${{ steps.release_notes.outputs.RELEASE_URL }} + EOF + + cat "$TEMPFILE" >> "$GITHUB_STEP_SUMMARY"