diff --git a/.github/workflows/check_gradle_all.yaml b/.github/workflows/check_gradle_all.yaml index eea6ec74f..c034fc2b0 100644 --- a/.github/workflows/check_gradle_all.yaml +++ b/.github/workflows/check_gradle_all.yaml @@ -2,8 +2,8 @@ name: 🐘 Gradle | Check All on: - workflow_dispatch: - workflow_call: + pull_request: + types: [ opened, synchronize, reopened ] jobs: check_gradle: diff --git a/.github/workflows/comment_on_pr.yaml b/.github/workflows/comment_on_pr.yaml index 67b1eb01d..6e6381087 100644 --- a/.github/workflows/comment_on_pr.yaml +++ b/.github/workflows/comment_on_pr.yaml @@ -1,7 +1,11 @@ name: 💬 Comment on PR on: - workflow_call: + workflow_run: + types: + - "completed" + workflows: + - "🐘 Gradle | Check All" jobs: comment-on-pr: diff --git a/.github/workflows/lint_yaml.yaml b/.github/workflows/lint_yaml.yaml index c01ab2300..870fa475c 100644 --- a/.github/workflows/lint_yaml.yaml +++ b/.github/workflows/lint_yaml.yaml @@ -2,8 +2,8 @@ name: 🔎 Lint Yaml on: - workflow_dispatch: - workflow_call: + pull_request: + types: [ opened, synchronize, reopened ] jobs: lint_yaml: diff --git a/.github/workflows/on_pr_updated.yaml b/.github/workflows/on_pr_updated.yaml deleted file mode 100644 index d4ed63c76..000000000 --- a/.github/workflows/on_pr_updated.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: ⬇️ PR Updated - -on: - pull_request: - types: [opened, synchronize, reopened] - -jobs: - call_gradle_check: - name: ☎️ Call Gradle Check - uses: ./.github/workflows/check_gradle_all.yaml - secrets: inherit - - call_lint_yaml: - name: ☎️ Call Lint Yaml - uses: ./.github/workflows/lint_yaml.yaml - secrets: inherit diff --git a/.github/workflows/on_pr_updated_completed.yaml b/.github/workflows/on_pr_updated_completed.yaml deleted file mode 100644 index bab962785..000000000 --- a/.github/workflows/on_pr_updated_completed.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: ✅ PR Updated Completed - -on: - workflow_run: - types: - - "completed" - workflows: - - "⬇️ PR Updated" - -jobs: - call_comment_on_pr: - name: ☎️ Call Comment on PR - uses: ./.github/workflows/check_gradle_all.yaml - secrets: inherit diff --git a/.github/workflows/on_tag_pushed.yaml b/.github/workflows/on_tag_pushed.yaml deleted file mode 100644 index 508b6006e..000000000 --- a/.github/workflows/on_tag_pushed.yaml +++ /dev/null @@ -1,49 +0,0 @@ -# Publish and release a project when a tag is created. -# TODO: Currently, this only supports plugins. -name: 🏷️ Tag Pushed - -on: - push: - tags: - - '*/v*.*.*' - -jobs: - split_values: - name: ✂️ Split Values - runs-on: ubuntu-latest - - outputs: - version: ${{ steps.split_version.outputs.version }} - project: ${{ steps.split_project.outputs.project }} - - steps: - - name: ✂️ Split Project Version - id: split_version - env: - TAG: ${{ github.ref_name }} - run: echo "version=${TAG##*/}" >> $GITHUB_OUTPUT - - - name: ✂️ Split Project Name - id: split_project - env: - TAG: ${{ github.ref_name }} - VERSION: ${{steps.split_version.outputs.version }} - run: echo "project=${TAG///$VERSION}" >> $GITHUB_OUTPUT - - call_publish_gradle: - needs: split_values - name: ☎️ Call Publish Gradle - uses: ./.github/workflows/publish_gradle_project.yaml - secrets: inherit - with: - category: plugins - project: ${{ needs.split_values.outputs.project }} - - call_release_gradle: - needs: split_values - name: ☎️ Call Release Gradle - uses: ./.github/workflows/release_gradle_project.yaml - secrets: inherit - with: - category: plugins - project: ${{ needs.split_values.outputs.project }} diff --git a/.github/workflows/publish_container.yaml b/.github/workflows/publish_container.yaml new file mode 100644 index 000000000..545f69051 --- /dev/null +++ b/.github/workflows/publish_container.yaml @@ -0,0 +1,82 @@ +# Publish a container +name: 🐋 Container | Publish + +on: + push: + tags: + - 'containers/*/v*.*.*' + +jobs: + determine_values: + name: 🔎 Determine Values + runs-on: ubuntu-latest + + outputs: + category: ${{ steps.determine_values.outputs.category }} + version: ${{ steps.determine_values.outputs.version }} + project: ${{ steps.determine_values.outputs.project }} + + steps: + - name: 🔎 Determine Project Values + id: determine_values + env: + TAG: ${{ github.ref_name }} + run: | + category=${TAG%%/*} + echo "category=${category}" + echo "category=${category}" >> $GITHUB_OUTPUT + + version=${TAG##*/} + echo "version=${version}" + echo "version=${version}" >> $GITHUB_OUTPUT + + project=${TAG#*/} + project=${project%/*} + echo "project=${project}" + echo "project=${project}" >> $GITHUB_OUTPUT + + publish_container: + name: 🐋 Publish Container + needs: determine_values + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + steps: + - name: 🚩 Checkout Repo + uses: actions/checkout@v4 + + - name: 🔎 Introspect metadata + id: metadata + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/civmc/civ/${{needs.determine_values.outputs.project}} + tags: | + type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + type=ref,event=branch + type=semver,pattern={{version}},value=${{needs.determine_values.outputs.version}} + type=semver,pattern={{major}}.{{minor}},value=${{needs.determine_values.outputs.version}} + type=semver,pattern={{major}},value=${{needs.determine_values.outputs.version}} + + - name: 🪵 Login to Github Packages + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: 🗃️ Create/Update Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ needs.determine_values.outputs.category }}/${{ needs.determine_values.outputs.project }}/${{ needs.determine_values.outputs.version }} + + - name: 🐳 Build and push + uses: docker/build-push-action@v5 + with: + context: containers/${{needs.determine_values.outputs.project}} + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} diff --git a/.github/workflows/publish_gradle_project.yaml b/.github/workflows/publish_gradle_project.yaml index cc2ae3f61..b7c0f8693 100644 --- a/.github/workflows/publish_gradle_project.yaml +++ b/.github/workflows/publish_gradle_project.yaml @@ -1,36 +1,47 @@ -# Publish a project to maven +# Release a gradle project +# Publish to maven, and create/update name: 🐘 Gradle | Publish Project on: - workflow_dispatch: - inputs: - category: - required: true - description: 'The category of project' - type: choice - options: - - plugins - project: - required: true - description: 'The project to publish' - type: string - workflow_call: - inputs: - category: - required: true - description: 'The category of project' - type: string - project: - required: true - description: 'The project to publish' - type: string + push: + tags: + - 'plugins/*/v*.*.*' jobs: + determine_values: + name: 🔎 Determine Values + runs-on: ubuntu-latest + + outputs: + category: ${{ steps.determine_values.outputs.category }} + version: ${{ steps.determine_values.outputs.version }} + project: ${{ steps.determine_values.outputs.project }} + + steps: + - name: 🔎 Determine Project Values + id: determine_values + env: + TAG: ${{ github.ref_name }} + run: | + category=${TAG%%/*} + echo "category=${category}" + echo "category=${category}" >> $GITHUB_OUTPUT + + version=${TAG##*/} + echo "version=${version}" + echo "version=${version}" >> $GITHUB_OUTPUT + + project=${TAG#*/} + project=${project%/*} + echo "project=${project}" + echo "project=${project}" >> $GITHUB_OUTPUT + publish_gradle: name: 🐘 Publish Gradle runs-on: ubuntu-latest + needs: determine_values permissions: - contents: read + contents: write packages: write steps: @@ -46,10 +57,25 @@ jobs: java-version: '17' distribution: 'temurin' + # TODO: Bump version if not already done + + - name: 🐘 Gradle Build + uses: gradle/gradle-build-action@v2 + env: + CI: true + with: + arguments: "${{needs.determine_values.outputs.category}}:${{needs.determine_values.outputs.project}}:build --scan" + + - name: 🗃️ Create/Update Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ needs.determine_values.outputs.category }}/${{ needs.determine_values.outputs.project }}/${{ needs.determine_values.outputs.version }} + files: '${{needs.determine_values.outputs.category}}/${{needs.determine_values.outputs.project}}/build/libs/*' + - name: 🐘 Gradle Publish uses: gradle/gradle-build-action@v2 env: CI: true GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - arguments: "${{inputs.category}}:${{inputs.project}}:publish --scan" + arguments: "${{needs.determine_values.outputs.category}}:${{needs.determine_values.outputs.project}}:publish --scan" diff --git a/.github/workflows/release_gradle_project.yaml b/.github/workflows/release_gradle_project.yaml deleted file mode 100644 index 1ade5443e..000000000 --- a/.github/workflows/release_gradle_project.yaml +++ /dev/null @@ -1,58 +0,0 @@ -# Attach artifacts to a github release -name: 🐘 Gradle | Release Project - -on: - workflow_dispatch: - inputs: - category: - required: true - description: 'The category of project' - type: choice - options: - - plugins - project: - required: true - description: 'The project to build' - type: string - workflow_call: - inputs: - category: - required: true - description: 'The category of project' - type: string - project: - required: true - description: 'The project to build' - type: string - -jobs: - release_gradle: - name: 🐘 Release Gradle - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - name: 🚩 Checkout Repo - uses: actions/checkout@v4 - - - name: ❓ Ensure Wrapper Permissions - run: chmod +x ./gradlew - - - name: ☕ Setup Java - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: 🐘 Gradle Build - uses: gradle/gradle-build-action@v2 - env: - CI: true - with: - arguments: "${{inputs.category}}:${{inputs.project}}:build --scan" - - - name: 🗃️ Create Release - uses: softprops/action-gh-release@v1 - with: - files: '${{inputs.category}}/${{inputs.project}}/build/libs/*' diff --git a/.gitignore b/.gitignore index 00e1ba12f..7a7b2f3a4 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ build run temp + + +### Docker ### +containers/data diff --git a/README.md b/README.md new file mode 100644 index 000000000..dbdcf92d9 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Civ + +This monorepo will eventually contain all civ projects and development + +## Developing Locally + +### Plugins + +### Containers +A docker compose stack is provided to help test containers built from +this repo. To start the stack, run the following command: +`docker compose up --build`. Please note that this stack is NOT suitable for production use. + +Optional services may be started by enabling the profile flag, e.g. `--profile ` + +Current services and exposed ports are: + +| Name | Ports | Description | Profile | +|----------|-------|---------------------|------------| +| pvp | | | | +| mariadb | 3306 | TCP, Database | | +| postgres | 5432 | TCP, Database | | +| rabbitmq | 5672 | TCP, AMQP | | +| | 15672 | HTTP, Management UI | | +| grafana | 3000 | HTTP, Grafana UI | monitoring | diff --git a/containers/provisioning/grafana/dashboards/default.yml b/containers/provisioning/grafana/dashboards/default.yml new file mode 100644 index 000000000..b71f4513b --- /dev/null +++ b/containers/provisioning/grafana/dashboards/default.yml @@ -0,0 +1,9 @@ +# TODO: Can't figure this out yet. Manually impory the dashboard. + +#apiVersion: 1 +# +#providers: +# - name: 'dashboards' +# options: +# path: +# /etc/grafana/provisioning/dashboards/files \ No newline at end of file diff --git a/containers/provisioning/grafana/dashboards/files/unified-metrics.json b/containers/provisioning/grafana/dashboards/files/unified-metrics.json new file mode 100644 index 000000000..bc6df24f1 --- /dev/null +++ b/containers/provisioning/grafana/dashboards/files/unified-metrics.json @@ -0,0 +1,3101 @@ +{ + "__inputs": [ + { + "name": "DS_INFLUXDB", + "label": "InfluxDB", + "description": "", + "type": "datasource", + "pluginId": "influxdb", + "pluginName": "InfluxDB" + }, + { + "name": "VAR_BUCKET", + "type": "constant", + "label": "Bucket", + "value": "unifiedmetrics", + "description": "" + } + ], + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "8.0.6" + }, + { + "type": "datasource", + "id": "influxdb", + "name": "InfluxDB", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Fully-featured metrics collection agent for Minecraft servers.", + "editable": true, + "gnetId": 14755, + "graphTooltip": 0, + "id": null, + "iteration": 1627190826103, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": "${DS_INFLUXDB}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 70, + "panels": [], + "title": "Overview", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 1 + }, + "id": 5, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "time()-avg(process_start_time_seconds{instance=~\"$instance\",job=\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "currentSeconds = (int(v: now()) / 1000000000)\r\n\r\nfrom(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"process_start_time_seconds\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> map(fn: (r) => ({ r with _value: currentSeconds - int(v: r._value) }))\r\n |> mean()", + "rawQuery": true, + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + " / 100" + ], + "type": "math" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Uptime (Mean)", + "transformations": [ + { + "id": "calculateField", + "options": { + "alias": "uptime", + "binary": { + "left": "_time", + "operator": "-", + "reducer": "sum", + "right": "last" + }, + "mode": "binary", + "reduce": { + "reducer": "delta" + }, + "replaceFields": true + } + } + ], + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 4, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "hide": false, + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_players_count\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> sum()", + "refId": "B" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Players", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 14, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "sum(minecraft_world_entities_count{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_entities_count\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> sum()", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Entities", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 1 + }, + "id": 15, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "sum(minecraft_world_loaded_chunks{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_loaded_chunks\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> sum()", + "rawQuery": true, + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 20, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "#EAB839", + "value": 17 + }, + { + "color": "orange", + "value": 18 + }, + { + "color": "green", + "value": 19 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 6 + }, + "id": 3, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "avg(minecraft_tps{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_tick_duration_seconds\" and r._field == \"count\" and r.server =~ /^${server:pipe}$/)\r\n |> derivative(unit: 1s)\r\n |> last()\r\n |> group()\r\n |> mean()", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "TPS (Mean)", + "type": "gauge" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 0.05, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.02 + }, + { + "color": "orange", + "value": 0.03 + }, + { + "color": "red", + "value": 0.04 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 6 + }, + "id": 13, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "avg(minecraft_tick_duration_seconds{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "import \"experimental\"\r\n\r\ndoQuantile = (tables=<-, q) => tables\r\n |> histogramQuantile(quantile: q)\r\n |> duplicate(as: \"_time\", column: \"_stop\")\r\n |> window(every: inf)\r\n |> map(fn: (r) => ({r with _measurement: \"quantile\", _field: string(v: q)}))\r\n |> experimental.group(mode: \"extend\", columns: [\"_measurement\", \"_field\"])\r\n\r\nhistograms =\r\n from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_tick_duration_seconds\" and r._field != \"count\" and r._field != \"sum\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(fn: last, every: v.windowPeriod)\r\n |> difference(nonNegative: true)\r\n |> filter(fn: (r) => exists r._value)\r\n |> group(columns: [\"_field\"])\r\n |> window(every: v.windowPeriod)\r\n |> sum()\r\n |> map(fn: (r) => ({r with le: float(v: r._field)}))\r\n |> drop(columns: [\"_field\"])\r\n\r\nhistograms |> doQuantile(q: 0.5)\r\n", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "MSPT (Mean)", + "type": "gauge" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.7 + }, + { + "color": "orange", + "value": 0.8 + }, + { + "color": "red", + "value": 0.9 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 6 + }, + "id": 19, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "sum(process_cpu_load_ratio{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"process_cpu_load_ratio\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> sum()", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Load (Total)", + "type": "gauge" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 6 + }, + "id": 20, + "interval": "$interval", + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "expr": "sum(jvm_memory_bytes_used{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "instant": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_memory_bytes_used\" and r.server =~ /^${server:pipe}$/)\r\n |> last()\r\n |> group()\r\n |> sum()", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory (Total)", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "${DS_INFLUXDB}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 78, + "panels": [], + "title": "Server", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "displayName": "tps: ${__field.labels.server}", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 11, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "min", + "max", + "mean" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "$server: minecraft_tps", + "expr": "minecraft_tps{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_tick_duration_seconds\" and r._field == \"count\" and r.server =~ /^${server:pipe}$/)\r\n |> derivative(unit: 1s)\r\n |> aggregateWindow(every: v.windowPeriod, fn: (tables=<-, column) => tables)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "TPS", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "line" + } + }, + "displayName": "mspt: ${__field.name} quantile", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 0.05 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 12, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "$server: minecraft_tick_duration_seconds", + "expr": "minecraft_tick_duration_seconds{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "import \"experimental\"\r\n\r\ndoQuantile = (tables=<-, q) => tables\r\n |> histogramQuantile(quantile: q)\r\n |> duplicate(as: \"_time\", column: \"_stop\")\r\n |> window(every: inf)\r\n |> map(fn: (r) => ({r with _measurement: \"quantile\", _field: string(v: q)}))\r\n |> experimental.group(mode: \"extend\", columns: [\"_measurement\", \"_field\"])\r\n\r\nhistograms =\r\n from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_tick_duration_seconds\" and r._field != \"count\" and r._field != \"sum\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(fn: last, every: v.windowPeriod)\r\n |> difference(nonNegative: true)\r\n |> filter(fn: (r) => exists r._value)\r\n |> group(columns: [\"_field\"])\r\n |> window(every: v.windowPeriod)\r\n |> sum()\r\n |> map(fn: (r) => ({r with le: float(v: r._field)}))\r\n |> drop(columns: [\"_field\"])\r\n\r\nunion(tables: [\r\n histograms |> doQuantile(q: 0.99),\r\n histograms |> doQuantile(q: 0.95),\r\n histograms |> doQuantile(q: 0.75),\r\n histograms |> doQuantile(q: 0.5),\r\n])\r\n", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "MSPT", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "displayName": "players: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 23 + }, + "id": 17, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "$server: minecraft_players_count", + "expr": "minecraft_players_count{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_players_count\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Players", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "displayName": "${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 23 + }, + "id": 18, + "interval": "$interval", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "events: join", + "expr": "sum(increase(minecraft_events_join_total{instance=~\"$instance\",job=~\"$job\"}[5m]))", + "format": "time_series", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "intervalFactor": 1, + "legendFormat": "events: join", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_players_count\" and r.server =~ /^${server:pipe}$/)\r\n |> difference()\r\n |> aggregateWindow(every: v.windowPeriod, fn: sum)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Player flow", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": "${DS_INFLUXDB}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 33 + }, + "id": 86, + "panels": [], + "repeat": "world", + "title": "World [$world]", + "type": "row" + }, + { + "datasource": "$datasource", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "chunks: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 34 + }, + "id": 38, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "world: chunks", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_loaded_chunks\" and r.server =~ /^${server:pipe}$/ and r.world =~ /^${world:pipe}$/)\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Chunks", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "${__field.name}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 34 + }, + "id": 33, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "world: entities", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_entities_count\" and r.server =~ /^${server:pipe}$/ and r.world =~ /^${world:pipe}$/)\r\n |> map(fn: (r) => ({ r with _field: \"players: ${r.server}\" }))\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + }, + { + "alias": "world: entities", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_players_count\" and r.server =~ /^${server:pipe}$/ and r.name =~ /^${world:pipe}$/)\r\n |> map(fn: (r) => ({ r with _field: \"entities: ${r.server}\" }))\r\n |> aggregateWindow(every: ${interval}, fn: (tables=<-, column) => tables)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Entities", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": "${DS_INFLUXDB}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 132 + }, + "id": 94, + "panels": [], + "title": "JVM: Computation", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "cpu_ratio: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 133 + }, + "id": 24, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "$server: process_cpu_load_ratio", + "expr": "process_cpu_load_ratio{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"process_cpu_load_ratio\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Usage", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "cpu_seconds: ${__field.labels.server}", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 133 + }, + "id": 45, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "$server: process_cpu_seconds_total", + "expr": "rate(process_cpu_seconds_total{instance=~\"$instance\",job=~\"$job\"}[1m])", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "process_cpu_seconds_total{instance=''{{instance}}\", job=\"{{job}}\"}", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"process_cpu_seconds_total\" and r.server =~ /^${server:pipe}$/)\r\n |> derivative(unit: 1s)\r\n |> aggregateWindow(every: v.windowPeriod, fn: (tables=<-, column) => tables)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "CPU Time (per second)", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "threads: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 0, + "y": 144 + }, + "id": 25, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.5", + "targets": [ + { + "alias": "$server: jvm_threads_current_count", + "expr": "jvm_threads_current_count{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_threads_current_count\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Threads", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "daemons: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 8, + "y": 144 + }, + "id": 98, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.5", + "targets": [ + { + "alias": "$server: jvm_threads_current_count", + "expr": "jvm_threads_current_count{instance=~\"$instance\",job=~\"$job\"}", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_threads_daemon_count\" and r.server =~ /^${server:pipe}$/)\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Daemons", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "displayName": "threads_started: ${__field.labels.server}", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 144 + }, + "id": 46, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "threads: started", + "expr": "sum(increase(jvm_threads_started_total{instance=~\"$instance\",job=~\"$job\"}[1m]))", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "jvm_threads_started_total", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_threads_started_total\" and r.server =~ /^${server:pipe}$/)\r\n |> difference()\r\n |> aggregateWindow(every: v.windowPeriod, fn: sum)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Threads started", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 155 + }, + "id": 100, + "panels": [], + "title": "JVM: Memory", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "heap: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 156 + }, + "id": 26, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.5", + "targets": [ + { + "alias": "memory: used", + "expr": "sum(jvm_memory_bytes_used{instance=~\"$instance\",job=~\"$job\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "hide": false, + "interval": "", + "legendFormat": "memory: used", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_memory_bytes_used\" and r.server =~ /^${server:pipe}$/ and r.area == \"heap\")\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Heap Memory", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "displayName": "nonheap: ${__field.labels.server}", + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 156 + }, + "id": 27, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "mean", + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.5", + "targets": [ + { + "alias": "nonheap: used", + "expr": "sum(jvm_memory_bytes_used{instance=~\"$instance\",job=~\"$job\",area=\"heap\"})", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "heap: used", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_memory_bytes_used\" and r.server =~ /^${server:pipe}$/ and r.area == \"nonheap\")\r\n |> aggregateWindow(every: v.windowPeriod, fn: last)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Non-heap Memory", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "displayName": "gc_duration: ${__field.labels.gc}", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 0, + "y": 167 + }, + "id": 111, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "max" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "threads: started", + "expr": "sum(increase(jvm_threads_started_total{instance=~\"$instance\",job=~\"$job\"}[1m]))", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "jvm_threads_started_total", + "orderByTime": "ASC", + "policy": "default", + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_gc_duration_seconds\" and r._field == \"sum\" and r.server =~ /^${server:pipe}$/)\r\n |> group(columns: [\"gc\"])\r\n |> difference()\r\n |> aggregateWindow(every: v.windowPeriod, fn: sum)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "GC Duration (Total)", + "type": "timeseries" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 0, + "displayName": "gc_freed: ${__field.labels.gc}", + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 12, + "x": 12, + "y": 167 + }, + "id": 112, + "interval": "$interval", + "options": { + "legend": { + "calcs": [ + "max", + "min" + ], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "pluginVersion": "8.0.4", + "targets": [ + { + "alias": "threads: started", + "expr": "sum(increase(jvm_threads_started_total{instance=~\"$instance\",job=~\"$job\"}[1m]))", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "interval": "", + "legendFormat": "jvm_threads_started_total", + "orderByTime": "ASC", + "policy": "default", + "query": " from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r._measurement == \"jvm_gc_freed_bytes\" and r._field == \"sum\" and r.server =~ /^${server:pipe}$/)\r\n |> group(columns: [\"gc\"])\r\n |> difference()\r\n |> aggregateWindow(every: v.windowPeriod, fn: sum)\r\n", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "GC Freed (Total)", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "InfluxDB", + "value": "InfluxDB" + }, + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "influxdb", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": {}, + "datasource": "${DS_INFLUXDB}", + "definition": "import \"influxdata/influxdb/v1\"\r\n\r\nv1.measurementTagValues(\r\n bucket: \"${bucket}\",\r\n measurement: \"minecraft_players_count\",\r\n tag: \"server\"\r\n)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "server", + "options": [], + "query": "import \"influxdata/influxdb/v1\"\r\n\r\nv1.measurementTagValues(\r\n bucket: \"${bucket}\",\r\n measurement: \"minecraft_players_count\",\r\n tag: \"server\"\r\n)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "selected": false, + "text": "10s", + "value": "10s" + }, + "description": null, + "error": null, + "hide": 0, + "label": null, + "name": "interval", + "options": [ + { + "selected": false, + "text": "5s", + "value": "5s" + }, + { + "selected": true, + "text": "10s", + "value": "10s" + }, + { + "selected": false, + "text": "15s", + "value": "15s" + }, + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "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": "5s,10s,15s,30s,1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "queryValue": "", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + }, + { + "allValue": null, + "current": {}, + "datasource": "$datasource", + "definition": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_players_count\" and r.server =~ /^${server:pipe}$/)\r\n |> keyValues(keyColumns: [\"world\"])\r\n |> group()\r\n |> keep(columns: [\"world\"])", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "world", + "options": [], + "query": "from(bucket: \"${bucket}\")\r\n |> range(start: v.timeRangeStart)\r\n |> filter(fn: (r) => r._measurement == \"minecraft_world_players_count\" and r.server =~ /^${server:pipe}$/)\r\n |> keyValues(keyColumns: [\"world\"])\r\n |> group()\r\n |> keep(columns: [\"world\"])", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "description": null, + "error": null, + "hide": 2, + "label": "Bucket", + "name": "bucket", + "query": "${VAR_BUCKET}", + "skipUrlSync": false, + "type": "constant", + "current": { + "value": "${VAR_BUCKET}", + "text": "${VAR_BUCKET}", + "selected": false + }, + "options": [ + { + "value": "${VAR_BUCKET}", + "text": "${VAR_BUCKET}", + "selected": false + } + ] + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "UnifiedMetrics 0.3.x / InfluxDB Flux", + "uid": "xU08wAW7z", + "version": 3 +} \ No newline at end of file diff --git a/containers/provisioning/grafana/datasources/influx.yml b/containers/provisioning/grafana/datasources/influx.yml new file mode 100644 index 000000000..3578ba2bc --- /dev/null +++ b/containers/provisioning/grafana/datasources/influx.yml @@ -0,0 +1,13 @@ +apiVersion: 1 + +datasources: + - name: InfluxDB + type: influxdb + access: proxy + url: ${CIV_INFLUX_HOST} + secureJsonData: + token: ${CIV_INFLUX_TOKEN} + jsonData: + version: Flux + organization: ${CIV_INFLUX_ORG} + tlsSkipVerify: true diff --git a/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql b/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql new file mode 100644 index 000000000..3a8e8c4bb --- /dev/null +++ b/containers/provisioning/mariadb/docker-entrypoint-initdb.d/0100_create_databases.sql @@ -0,0 +1,27 @@ +CREATE DATABASE donum; +CREATE DATABASE banstick; +CREATE DATABASE bastion; +CREATE DATABASE citadel; +CREATE DATABASE civchat2; +CREATE DATABASE civduties; +CREATE DATABASE jukealert; +CREATE DATABASE namelayer; +CREATE DATABASE civmodcore; +CREATE DATABASE castlegates; +CREATE DATABASE essenceglue; +CREATE DATABASE exilepearl; +CREATE DATABASE realisticbiomes; + +GRANT ALL PRIVILEGES ON `donum`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `banstick`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `bastion`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `citadel`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `civchat2`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `civduties`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `jukealert`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `namelayer`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `civmodcore`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `castlegates`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `essenceglue`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `exilepearl`.* TO 'mariadb'@'%'; +GRANT ALL PRIVILEGES ON `realisticbiomes`.* TO 'mariadb'@'%'; diff --git a/containers/provisioning/postgres/docker-entrypoint-initdb.d/0100_create_databases.sql b/containers/provisioning/postgres/docker-entrypoint-initdb.d/0100_create_databases.sql new file mode 100644 index 000000000..43a2389b2 --- /dev/null +++ b/containers/provisioning/postgres/docker-entrypoint-initdb.d/0100_create_databases.sql @@ -0,0 +1,6 @@ +CREATE DATABASE kira; +CREATE DATABASE luckperms; + +CREATE DATABASE civspy; +\c civspy; +CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; \ No newline at end of file diff --git a/containers/pvp/Dockerfile b/containers/pvp/Dockerfile new file mode 100644 index 000000000..cb42cbd94 --- /dev/null +++ b/containers/pvp/Dockerfile @@ -0,0 +1,24 @@ +# Pin to java17 +FROM itzg/minecraft-server@sha256:346cb47929edc36e977f3b064f882a9c919df65fe4807ac35c05fdacf442822f + +# https://github.com/itzg/docker-minecraft-server/blob/master/README.md#versions +ENV VERSION=1.18.2 + +# https://github.com/itzg/docker-minecraft-server#optional-plugins-mods-and-config-attach-points +COPY plugins /plugins +ENV REMOVE_OLD_MODS=TRUE + +# https://github.com/itzg/docker-minecraft-server#optional-plugins-mods-and-config-attach-points +COPY config /config +ENV COPY_CONFIG_DEST=/data +ENV SYNC_SKIP_NEWER_IN_DESTINATION=false + +# https://github.com/itzg/docker-minecraft-server#running-a-paper-server +ENV TYPE=PAPER +ENV EULA=TRUE +ENV USE_AIKAR_FLAGS=TRUE +# https://github.com/itzg/docker-minecraft-server#replacing-variables-inside-configs +ENV REPLACE_ENV_DURING_SYNC=TRUE +ENV REPLACE_ENV_VARIABLE_PREFIX=CIV + +ENV CIV_WHITELIST=false diff --git a/containers/pvp/config/ops.json b/containers/pvp/config/ops.json new file mode 100644 index 000000000..9be1761a0 --- /dev/null +++ b/containers/pvp/config/ops.json @@ -0,0 +1,32 @@ +[ + { + "uuid": "771e81cd-2f11-43b4-bd86-731fe468f131", + "name": "Wingzero54", + "level": 4, + "bypassesPlayerLimit": true + }, + { + "uuid": "54b84e38-ac83-43c0-b285-8c7163343488", + "name": "Ahrimanne", + "level": 4, + "bypassesPlayerLimit": true + }, + { + "uuid": "6e8e4f6f-a414-4f13-962c-6d914363788a", + "name": "SoundTech", + "level": 4, + "bypassesPlayerLimit": true + }, + { + "uuid": "82569b12-c44c-4864-8a73-85a9192ee8f9", + "name": "RedDevel", + "level": 4, + "bypassesPlayerLimit": true + }, + { + "uuid": "2c7c20f7-8472-4780-9b35-4cd4fae460c6", + "name": "Okx", + "level": 4, + "bypassesPlayerLimit": true + } +] diff --git a/containers/pvp/config/plugins/TAB/config.yml b/containers/pvp/config/plugins/TAB/config.yml new file mode 100644 index 000000000..76703626b --- /dev/null +++ b/containers/pvp/config/plugins/TAB/config.yml @@ -0,0 +1,226 @@ +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Header-&-Footer +header-footer: + enabled: true + disable-in-worlds: + - disabledworld + header: + - '&6&kAAAA&r&6&l Welcome to CivMC! &r&6&kAAAA' + - "&7Online players: &f%online%" + footer: + - '&9Modmail at &6reddit.com/r/civmc' + - '&a%tps% TPS &r&6discord.gg/nDnsU6vJqg' + - '&cPatreon: &6patreon.com/Civ_MC' + - '&6Admins: Wingzero54, Ahrimanne, SoundTech, RedDevel, Okx' + per-world: + world1: + header: + - "an example of world with custom" + footer: + - "header/footer and prefix/suffix" + world2;world3: + header: + - "This is a shared header for" + - "world2 and world3" + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Tablist-name-formatting +tablist-name-formatting: + enabled: true + align-tabsuffix-on-the-right: false + character-width-overrides: {} + anti-override: true + disable-in-worlds: + - disabledworld + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Nametags +scoreboard-teams: + enabled: false + enable-collision: true + invisible-nametags: false + anti-override: true + # https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Sorting-players-in-tablist + sorting-types: + - "GROUPS:owner,admin,mod,helper,builder,vip,default" + - "PLACEHOLDER_A_TO_Z:%player%" + case-sensitive-sorting: true + disable-in-worlds: + - disabledworld + # https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Unlimited-nametag-mode + unlimited-nametag-mode: + enabled: false + use-marker-tag-for-1-8-x-clients: false + disable-on-boats: true + space-between-lines: 0.22 + disable-in-worlds: + - disabledworld + dynamic-lines: + - abovename + - nametag #the original one, combination of tagprefix + customtagname + tagsuffix + - belowname + - another + static-lines: + myCustomLine: 0.66 + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Yellow-number +yellow-number-in-tablist: + enabled: false + value: "%ping%" + disable-in-worlds: + - disabledworld + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Belowname +belowname-objective: + enabled: false + number: "%health%" + text: "&cHealth" + disable-in-worlds: + - disabledworld + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Spectator-fix +prevent-spectator-effect: + enabled: false + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Bossbar +bossbar: + enabled: false + toggle-command: /bossbar + remember-toggle-choice: false + hidden-by-default: false + disable-in-worlds: + - disabledworld + bars: + ServerInfo: + style: "PROGRESS" # for 1.9+: PROGRESS, NOTCHED_6, NOTCHED_10, NOTCHED_12, NOTCHED_20 + color: "%animation:barcolors%" # for 1.9+: BLUE, GREEN, PINK, PURPLE, RED, WHITE, YELLOW + progress: "100" # in % + text: "&fWebsite: &bwww.domain.com" + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Per-world-playerlist +per-world-playerlist: + enabled: false + # players with tab.staff will always see all players + allow-bypass-permission: false + # players in these worlds will always see all players + ignore-effect-in-worlds: + - ignoredworld + - build + shared-playerlist-world-groups: + lobby: + - lobby1 + - lobby2 + minigames: + - paintball + - bedwars + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Scoreboard +scoreboard: + enabled: false + toggle-command: /sb + remember-toggle-choice: false + hidden-by-default: false + use-numbers: false + static-number: 0 + delay-on-join-milliseconds: 0 + respect-other-plugins: true + disable-in-worlds: + - disabledworld + scoreboards: + admin: + # Only players with tab.scoreboard.admin can see this scoreboard, others will see scoreboard1 + display-condition: "permission:tab.scoreboard.admin" + title: "Admin scoreboard" + lines: + - "%animation:MyAnimation1%" + - "&6Online:" + - "* &eOnline&7: &f%online%&7/&4%maxplayers%" + - "* &eCurrent World&7: &f%worldonline%" + - "* &eStaff&7: &f%staffonline%" + - " " + - "&6Server Info:" + - "* &bTPS&7: %tps%" + - "* &bUptime&7: &f%server_uptime%" + - "* &bMemory&7: &f%memory-used%&7/&4%memory-max%" + - "%animation:MyAnimation1%" + scoreboard1: + title: "Default" + lines: + - "%animation:MyAnimation1%" + - "&6My Stats:" + - "* &eKills&7: &f%statistic_player_kills%" + - "* &eDeaths&7: &f%statistic_deaths%" + - "* &eHealth&7: &f%health%" + - " " + - "&6Personal Info:" + - "* &bRank&7: &f%group%" + - "* &bPing&7: &f%ping%&7ms" + - "* &bWorld&7: &f%world%" + - "%animation:MyAnimation1%" + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Ping-Spoof +ping-spoof: + enabled: true + value: 0 + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Pet-name-fix +fix-pet-names: + enabled: false + +placeholders: + date-format: "dd.MM.yyyy" + time-format: "[HH:mm:ss / h:mm a]" + time-offset: 0 + register-tab-expansion: false + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Placeholder-output-replacements +placeholder-output-replacements: + "%essentials_vanished%": + "yes": "&7| Vanished" + "no": "" + "%afk%": + true: " &o[AFK]&r" + false: "" + "%essentials_nickname%": + "%essentials_nickname%": "%player%" #placeholder did not parse correctly, show real name instead + +# https://github.com/NEZNAMY/TAB/wiki/Feature-guide:-Conditional-placeholders +conditions: + nick: # use it with %condition:nick% + conditions: + - "%player%=%essentials_nickname%" + yes: "%player%" + no: "~%essentials_nickname%" + +placeholderapi-refresh-intervals: + default-refresh-interval: 500 + server: + "%server_uptime%": 1000 + "%server_tps_1_colored%": 1000 + "%server_unique_joins%": 5000 + player: + "%player_health%": 200 + "%player_ping%": 1000 + "%vault_prefix%": 1000 + relational: + "%rel_factionsuuid_relation_color%": 1000 + +# assigning groups by permission nodes instead of taking them from permission plugin +assign-groups-by-permissions: false + +# if the option above is true, all groups are taken based on permissions and the one higher in this list is used as primary +# Warning! This is not sorting list and has nothing to do with sorting players in tablist! +primary-group-finding-list: + - Owner + - Admin + - Mod + - Helper + - default + +debug: false + +# https://github.com/NEZNAMY/TAB/wiki/MySQL +mysql: + enabled: false + host: 127.0.0.1 + port: 3306 + database: tab + username: user + password: password diff --git a/containers/pvp/plugins/TAB-3.1.1.jar b/containers/pvp/plugins/TAB-3.1.1.jar new file mode 100644 index 000000000..3865a086b Binary files /dev/null and b/containers/pvp/plugins/TAB-3.1.1.jar differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..716edeea8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,117 @@ +version: '3.9' + +# Development stack for Civ. This stack can be used to develop and test the server and plugins locally. +# Please note that this stack is NOT suitable for production use, as it exposes all service ports, and uses default passwords. + +services: + + ################# + ### Minecraft ### + ################# + + pvp: + build: containers/pvp + restart: unless-stopped + tty: true + stdin_open: true + depends_on: + mariadb: + condition: service_healthy + postgres: + condition: service_healthy + environment: + INIT_MEMORY: 1G + MAX_MEMORY: 5G + + CIV_SERVER_NAME: local-pvp + + CIV_MYSQL_HOST: mariadb + CIV_MYSQL_USERNAME: mariadb + CIV_MYSQL_PASSWORD: mariadb + + CIV_POSTGRES_HOST: postgres + CIV_POSTGRES_USERNAME: postgres + CIV_POSTGRES_PASSWORD: postgres + + CIV_RABBITMQ_HOST: rabbitmq + CIV_RABBITMQ_USERNAME: rabbitmq + CIV_RABBITMQ_PASSWORD: rabbitmq + volumes: + - ./containers/data/pvp:/data + + ################# + ### Databases ### + ################# + + mariadb: + image: mariadb:10.7.1 + restart: unless-stopped + command: --max-connections 500 + healthcheck: + test: [ "CMD-SHELL", 'mysqladmin ping --user "$$MYSQL_USER" --password="$$MYSQL_PASSWORD"' ] + timeout: 20s + retries: 10 + ports: + - "3306:3306" + environment: + MYSQL_ROOT_PASSWORD: mariadb + MYSQL_USER: mariadb + MYSQL_PASSWORD: mariadb + MYSQL_DATABASE: mariadb + volumes: + - ./containers/provisioning/mariadb/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ./containers/data/mariadb:/var/lib/mysql + + postgres: + image: timescale/timescaledb:latest-pg14 + restart: unless-stopped + healthcheck: + test: [ "CMD-SHELL", 'pg_isready -U "$$POSTGRES_USER"' ] + interval: 10s + timeout: 5s + retries: 5 + ports: + - "5432:5432" + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + volumes: + - ./containers/provisioning/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + - ./containers/data/postgres:/var/lib/postgresql/data + + rabbitmq: + image: rabbitmq:3.9.16-management + restart: unless-stopped + healthcheck: + test: [ "CMD", "rabbitmq-diagnostics", "ping" ] + interval: 60s + timeout: 10s + retries: 5 + ports: + - "5672:5672" + - "15672:15672" + environment: + RABBITMQ_DEFAULT_USER: rabbitmq + RABBITMQ_DEFAULT_PASS: rabbitmq + + ################## + ### Monitoring ### + ################## + + grafana: + image: grafana/grafana-oss:latest + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + profiles: + - monitoring + ports: + - "3000:3000" + environment: + CIV_INFLUX_HOST: http://influx:8086 + CIV_INFLUX_ORG: CivMC + CIV_INFLUX_TOKEN: admintoken + volumes: + - ./containers/provisioning/grafana:/etc/grafana/provisioning