From 5121b6c54f78810837971726d7d4d168584a05ec Mon Sep 17 00:00:00 2001 From: eduardo aleixo Date: Thu, 24 Feb 2022 16:06:22 -0300 Subject: [PATCH] chore: use @pyroscope/panel-plugin (#6) * chore: use @pyroscope/panel-plugin --- .github/workflows/ci.yml | 40 +- .github/workflows/release.yml | 49 +- .gitignore | 4 +- CHANGELOG.md | 16 - LICENSE | 201 ---- README.md | 20 +- cypress.json | 1 + cypress/fixtures/simple-golang-app-cpu.json | 35 + cypress/integration/smoke.js | 13 + cypress/plugins/index.js | 22 + cypress/support/commands.js | 25 + cypress/support/index.js | 20 + docker-compose.yml | 6 +- .../dashboards/dashboard.json | 151 +++ grafana-provisioning/dashboards/main.yml | 8 + .../dashboards/single-panel.json | 67 ++ .../datasources/datasources.yml | 11 + grafana.ini | 976 ++++++++++++++++++ package.json | 13 +- yarn.lock | 461 ++++++++- 20 files changed, 1824 insertions(+), 315 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 LICENSE create mode 100644 cypress.json create mode 100644 cypress/fixtures/simple-golang-app-cpu.json create mode 100644 cypress/integration/smoke.js create mode 100644 cypress/plugins/index.js create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/index.js create mode 100644 grafana-provisioning/dashboards/dashboard.json create mode 100644 grafana-provisioning/dashboards/main.yml create mode 100644 grafana-provisioning/dashboards/single-panel.json create mode 100644 grafana-provisioning/datasources/datasources.yml create mode 100644 grafana.ini diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 301d8ba..6ce7e59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,8 @@ name: CI +env: + CYPRESS_CACHE_FOLDER: cypress/cache + on: pull_request: branches: @@ -27,38 +30,37 @@ jobs: key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - - name: Cache node_modules id: cache-node-modules uses: actions/cache@v2 with: path: node_modules - key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }} + key: ${{ runner.os }}-${{ matrix.node-version }}-node-modules-${{ hashFiles('**/yarn.lock') }} restore-keys: | - ${{ runner.os }}-${{ matrix.node-version }}-nodemodules- + ${{ runner.os }}-${{ matrix.node-version }}-node-modules- + - name: Cache Cypress Binary + id: cache-cypress-binary + uses: actions/cache@v2 + with: + path: cypress/cache + key: cypress-binary-${{ hashFiles('yarn.lock') }} - - name: Build plugin - run: yarn build + - name: Pull dependencies + run: yarn - name: Sign plugin - run: | - # We only have a single dependency, grafana-toolkit - # So we install next to where it's needed - yarn - yarn sign + run: yarn sign env: GRAFANA_API_KEY: ${{ secrets.GRAFANA_API_KEY }} # Requires a Grafana API key from Grafana.com. - # We reuse the same tests from the other repo, after all, why not? - # TODO: run other tests that are valid here - # eg: checking README etc + # Smoke test + # We already tested it extensively in the other repository - name: Run grafana server - run: docker-compose -f pyroscope/grafana-plugin/panel/docker-compose.yml up -d + run: docker-compose -f docker-compose.yml up -d - name: Run tests - run: yarn --cwd pyroscope cy:panel:ci + run: yarn cy:ci env: CYPRESS_VIDEO: true - CYPRESS_COMPARE_SNAPSHOTS: true - uses: actions/upload-artifact@v2 if: always() with: @@ -69,12 +71,6 @@ jobs: with: name: cypress-videos path: pyroscope/cypress/videos - - uses: actions/upload-artifact@v2 - if: always() - with: - name: cypress-snapshots - # TODO: scope to only store screenshots that refer to grafana - path: pyroscope/cypress/snapshots # Setup the go environment, since the grafana plugin linter isn't distributed as a binary - name: Setup Go environment diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 40ea16d..b9c15a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,55 +29,28 @@ jobs: key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - - name: Cache node_modules id: cache-node-modules uses: actions/cache@v2 with: path: node_modules - key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules-${{ hashFiles('**/yarn.lock') }} + key: ${{ runner.os }}-${{ matrix.node-version }}-node-modules-${{ hashFiles('**/yarn.lock') }} restore-keys: | - ${{ runner.os }}-${{ matrix.node-version }}-nodemodules- - - - name: Build plugin - run: yarn build + ${{ runner.os }}-${{ matrix.node-version }}-node-modules- + - name: Cache Cypress Binary + id: cache-cypress-binary + uses: actions/cache@v2 + with: + path: cypress/cache + key: cypress-binary-${{ hashFiles('yarn.lock') }} + - name: Pull dependencies + run: yarn - name: Sign plugin - run: | - # We only have a single dependency, grafana-toolkit - # So we install next to where it's needed - yarn - yarn sign + run: yarn sign env: GRAFANA_API_KEY: ${{ secrets.GRAFANA_API_KEY }} # Requires a Grafana API key from Grafana.com. - # We reuse the same tests from the other repo, after all, why not? - # TODO: run other tests that are valid here - # eg: checking README etc - - name: Run grafana server - run: docker-compose -f pyroscope/grafana-plugin/panel/docker-compose.yml up -d - - name: Run tests - run: yarn --cwd pyroscope cy:panel:ci - env: - CYPRESS_VIDEO: true - CYPRESS_COMPARE_SNAPSHOTS: true - - uses: actions/upload-artifact@v2 - if: always() - with: - name: cypress-screenshots - path: pyroscope/cypress/screenshots - - uses: actions/upload-artifact@v2 - if: always() - with: - name: cypress-videos - path: pyroscope/cypress/videos - - uses: actions/upload-artifact@v2 - if: always() - with: - name: cypress-snapshots - # TODO: scope to only store screenshots that refer to grafana - path: pyroscope/cypress/snapshots - # Setup the go environment, since the grafana plugin linter isn't distributed as a binary - name: Setup Go environment if: steps.check-for-backend.outputs.has-backend == 'true' diff --git a/.gitignore b/.gitignore index f9f0e92..3e32de2 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,7 @@ e2e-results/ # Editors .idea -src/flamegraphComponent.js -pyroscope dist.zip plugin-validator + +cypress/videos diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 4b18ff4..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# Changelog - -## 1.2.0 -* Remove broken export button -* Improve flamegraph coloring for go - -## 1.1.0 -* Add context menu (triggered by right clicking the flamegraph) -* Add toolbar -* Allow focusing on a subtree -* Allow searching nodes that match a specific string -* Visual updates - -## 1.0.0 - -Initial release. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8dada3e..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index c685105..a5f517b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,21 @@ # Pyroscope Grafana Panel Plugin +# Usage For more info see [pyroscope-panel plugin for Grafana | Grafana Labs](https://grafana.com/grafana/plugins/pyroscope-panel/) -or [pyroscope/grafana-plugin/panel at main · pyroscope-io/pyroscope](https://github.com/pyroscope-io/pyroscope/tree/main/grafana-plugin/panel) +or the source code [pyroscope/packages/pyroscope-panel-plugin at main · pyroscope-io/pyroscope](https://github.com/pyroscope-io/pyroscope/tree/main/packages/pyroscope-panel-plugin) +# Raison d'etre +The actual plugin development happens in the [main repo](https://github.com/pyroscope-io/pyroscope/tree/main/packages/pyroscope-panel-plugin). + +This repository is a simple wrapper around the `@pyroscope/panel-plugin` library. +It simply packages it, signs it and make a github release. +It does this for a couple reasons: +* So that we control the actual plugin release (since `@pyroscope/panel-plugin` release is automated) +* So that it's cleaner for users (The main repo releases refer to the pyroscope binary itself) + # Releasing new versions -1. Update the `UPSTREAM_BRANCH` in `build-panel.sh` -2. Update CHANGELOG.md -3. Bump the version in `package.json` -4. Merge to the main branch. +1. Update the `@pyroscope/panel-plugin` dependency +2. Open a Pull Request and merge it +3. Submit the new plugin version in Grafana Cloud (https://grafana.com/docs/grafana/latest/developers/plugins/package-a-plugin/#maintain-your-plugin) + diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/cypress.json @@ -0,0 +1 @@ +{} diff --git a/cypress/fixtures/simple-golang-app-cpu.json b/cypress/fixtures/simple-golang-app-cpu.json new file mode 100644 index 0000000..9fc275c --- /dev/null +++ b/cypress/fixtures/simple-golang-app-cpu.json @@ -0,0 +1,35 @@ +{ + "flamebearer": { + "names": [ + "total", + "runtime.main", + "main.slowFunction", + "main.work", + "main.main", + "main.fastFunction" + ], + "levels": [ + [0, 988, 0, 0], + [0, 988, 0, 1], + [0, 214, 0, 5, 0, 3, 2, 4, 0, 771, 0, 2], + [0, 214, 214, 3, 2, 1, 1, 5, 0, 771, 771, 3] + ], + "numTicks": 988, + "maxSelf": 771, + "spyName": "gospy", + "sampleRate": 100, + "units": "samples", + "format": "single" + }, + "metadata": { + "format": "single", + "sampleRate": 100, + "spyName": "gospy", + "units": "samples" + }, + "timeline": { + "startTime": 1632335270, + "samples": [989], + "durationDelta": 10 + } +} diff --git a/cypress/integration/smoke.js b/cypress/integration/smoke.js new file mode 100644 index 0000000..7a249d6 --- /dev/null +++ b/cypress/integration/smoke.js @@ -0,0 +1,13 @@ +// For these tests we can mock the requests +// Since we are only testing the panel itself +describe('smoke', () => { + it('renders the panel correctly', () => { + cy.intercept('**/render*', { + fixture: 'simple-golang-app-cpu.json', + }).as('render'); + + cy.visit('http://localhost:3000/d/single-panel/pyroscope-demo?orgId=1'); + + cy.get('[data-testid="flamegraph-canvas"]').should('exist'); + }); +}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 0000000..59b2bab --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,22 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 0000000..119ab03 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 0000000..d68db96 --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/docker-compose.yml b/docker-compose.yml index c830f3c..7d7b538 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,11 @@ -# this allows to test plugin very quickly -# run `./build-panel.sh` first -# then run `docker-compose up` ---- version: "3.9" services: grafana: image: grafana/grafana:8.1.1 volumes: - ./dist:/var/lib/grafana/plugins/pyroscope-panel + - ./grafana.ini:/etc/grafana/grafana.ini + - ./grafana-provisioning:/etc/grafana/provisioning environment: - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=pyroscope-panel - GF_INSTALL_PLUGINS=pyroscope-datasource diff --git a/grafana-provisioning/dashboards/dashboard.json b/grafana-provisioning/dashboards/dashboard.json new file mode 100644 index 0000000..78220f5 --- /dev/null +++ b/grafana-provisioning/dashboards/dashboard.json @@ -0,0 +1,151 @@ +{ + "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, + "gnetId": null, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": "Pyroscope", + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "seriesCountSize": "sm", + "showSeriesCount": false, + "text": "Default value of text input option" + }, + "targets": [ + { + "format": "json", + "from": "now-1h", + "name": "pyroscope.server.cpu", + "queryType": "randomWalk", + "refId": "A", + "until": "now" + } + ], + "title": "Panel Title", + "type": "pyroscope-panel" + }, + { + "datasource": "Pyroscope", + "gridPos": { + "h": 8, + "w": 7, + "x": 0, + "y": 10 + }, + "id": 3, + "options": { + "seriesCountSize": "sm", + "showSeriesCount": false, + "text": "Default value of text input option" + }, + "targets": [ + { + "format": "json", + "from": "now-1h", + "name": "pyroscope.server.cpu", + "queryType": "randomWalk", + "refId": "A", + "until": "now" + } + ], + "title": "Panel Title", + "type": "pyroscope-panel" + }, + { + "datasource": "Pyroscope", + "gridPos": { + "h": 8, + "w": 11, + "x": 7, + "y": 10 + }, + "id": 4, + "options": { + "seriesCountSize": "sm", + "showSeriesCount": false, + "text": "Default value of text input option" + }, + "targets": [ + { + "format": "json", + "from": "now-1h", + "name": "pyroscope.server.cpu", + "queryType": "randomWalk", + "refId": "A", + "until": "now" + } + ], + "title": "Panel Title", + "type": "pyroscope-panel" + }, + { + "datasource": "Pyroscope", + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 10 + }, + "id": 5, + "options": { + "seriesCountSize": "sm", + "showSeriesCount": false, + "text": "Default value of text input option" + }, + "targets": [ + { + "format": "json", + "from": "now-1h", + "name": "pyroscope.server.cpu", + "queryType": "randomWalk", + "refId": "A", + "until": "now" + } + ], + "title": "Panel Title", + "type": "pyroscope-panel" + } + ], + "refresh": "", + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Pyroscope demo", + "uid": "ZNBMoutnz", + "version": 3 +} diff --git a/grafana-provisioning/dashboards/main.yml b/grafana-provisioning/dashboards/main.yml new file mode 100644 index 0000000..736aa1f --- /dev/null +++ b/grafana-provisioning/dashboards/main.yml @@ -0,0 +1,8 @@ +apiVersion: 1 + +providers: + - name: dashboards + type: file + updateIntervalSeconds: 5 + options: + path: /etc/grafana/provisioning/dashboards diff --git a/grafana-provisioning/dashboards/single-panel.json b/grafana-provisioning/dashboards/single-panel.json new file mode 100644 index 0000000..cf42437 --- /dev/null +++ b/grafana-provisioning/dashboards/single-panel.json @@ -0,0 +1,67 @@ +{ + "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, + "gnetId": null, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": "Pyroscope", + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "showToolbar": false + }, + "targets": [ + { + "format": "json", + "from": "now-1h", + "name": "pyroscope.server.cpu", + "queryType": "randomWalk", + "refId": "A", + "until": "now" + } + ], + "title": "Panel Title", + "type": "pyroscope-panel" + } + ], + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Single Panel Dashboard", + "uid": "single-panel", + "version": 3 +} diff --git a/grafana-provisioning/datasources/datasources.yml b/grafana-provisioning/datasources/datasources.yml new file mode 100644 index 0000000..984bbd0 --- /dev/null +++ b/grafana-provisioning/datasources/datasources.yml @@ -0,0 +1,11 @@ +--- +apiVersion: 1 + +datasources: + - name: Pyroscope + type: pyroscope-datasource + access: proxy + orgId: 1 + uid: pyroscope + jsonData: + path: http://pyroscope:4040 diff --git a/grafana.ini b/grafana.ini new file mode 100644 index 0000000..9939cbb --- /dev/null +++ b/grafana.ini @@ -0,0 +1,976 @@ +##################### Grafana Configuration Example ##################### +# +# Everything has defaults so you only need to uncomment things you want to +# change + +# possible values : production, development +;app_mode = production + +# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty +;instance_name = ${HOSTNAME} + +#################################### Paths #################################### +[paths] +# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) +;data = /var/lib/grafana + +# Temporary files in `data` directory older than given duration will be removed +;temp_data_lifetime = 24h + +# Directory where grafana can store logs +;logs = /var/log/grafana + +# Directory where grafana will automatically scan and look for plugins +;plugins = /var/lib/grafana/plugins + +# folder that contains provisioning config files that grafana will apply on startup and while running. +provisioning = /etc/grafana/provisioning + +#################################### Server #################################### +[server] +# Protocol (http, https, h2, socket) +;protocol = http + +# The ip address to bind to, empty will bind to all interfaces +;http_addr = + +# The http port to use +;http_port = 3000 + +# The public facing domain name used to access grafana from a browser +;domain = localhost + +# Redirect to correct domain if host header does not match domain +# Prevents DNS rebinding attacks +;enforce_domain = false + +# The full public facing url you use in browser, used for redirects and emails +# If you use reverse proxy and sub path specify full url (with sub path) +;root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. +;serve_from_sub_path = false + +# Log web requests +;router_logging = false + +# the path relative working path +;static_root_path = public + +# enable gzip +;enable_gzip = false + +# https certs & key file +;cert_file = +;cert_key = + +# Unix socket path +;socket = + +# CDN Url +;cdn_url = + +# Sets the maximum time using a duration format (5s/5m/5ms) before timing out read of an incoming request and closing idle connections. +# `0` means there is no timeout for reading the request. +;read_timeout = 0 + +#################################### Database #################################### +[database] +# You can configure the database connection by specifying type, host, name, user and password +# as separate properties or as on string using the url properties. + +# Either "mysql", "postgres" or "sqlite3", it's your choice +;type = sqlite3 +;host = 127.0.0.1:3306 +;name = grafana +;user = root +# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" +;password = + +# Use either URL or the previous fields to configure the database +# Example: mysql://user:secret@host:port/database +;url = + +# For "postgres" only, either "disable", "require" or "verify-full" +;ssl_mode = disable + +# Database drivers may support different transaction isolation levels. +# Currently, only "mysql" driver supports isolation levels. +# If the value is empty - driver's default isolation level is applied. +# For "mysql" use "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ" or "SERIALIZABLE". +;isolation_level = + +;ca_cert_path = +;client_key_path = +;client_cert_path = +;server_cert_name = + +# For "sqlite3" only, path relative to data_path setting +;path = grafana.db + +# Max idle conn setting default is 2 +;max_idle_conn = 2 + +# Max conn setting default is 0 (mean not set) +;max_open_conn = + +# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours) +;conn_max_lifetime = 14400 + +# Set to true to log the sql calls and execution times. +;log_queries = + +# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared) +;cache_mode = private + +################################### Data sources ######################### +[datasources] +# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API. +;datasource_limit = 5000 + +#################################### Cache server ############################# +[remote_cache] +# Either "redis", "memcached" or "database" default is "database" +;type = database + +# cache connectionstring options +# database: will use Grafana primary database. +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'. +# memcache: 127.0.0.1:11211 +;connstr = + +#################################### Data proxy ########################### +[dataproxy] + +# This enables data proxy logging, default is false +;logging = false + +# How long the data proxy waits to read the headers of the response before timing out, default is 30 seconds. +# This setting also applies to core backend HTTP data sources where query requests use an HTTP client with timeout set. +;timeout = 30 + +# How long the data proxy waits to establish a TCP connection before timing out, default is 10 seconds. +;dialTimeout = 10 + +# How many seconds the data proxy waits before sending a keepalive probe request. +;keep_alive_seconds = 30 + +# How many seconds the data proxy waits for a successful TLS Handshake before timing out. +;tls_handshake_timeout_seconds = 10 + +# How many seconds the data proxy will wait for a server's first response headers after +# fully writing the request headers if the request has an "Expect: 100-continue" +# header. A value of 0 will result in the body being sent immediately, without +# waiting for the server to approve. +;expect_continue_timeout_seconds = 1 + +# The maximum number of idle connections that Grafana will keep alive. +;max_idle_connections = 100 + +# The maximum number of idle connections per host that Grafana will keep alive. +;max_idle_connections_per_host = 2 + +# How many seconds the data proxy keeps an idle connection open before timing out. +;idle_conn_timeout_seconds = 90 + +# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false. +;send_user_header = false + +#################################### Analytics #################################### +[analytics] +# Server reporting, sends usage counters to stats.grafana.org every 24 hours. +# No ip addresses are being tracked, only simple counters to track +# running instances, dashboard and error counts. It is very helpful to us. +# Change this option to false to disable reporting. +;reporting_enabled = true + +# The name of the distributor of the Grafana instance. Ex hosted-grafana, grafana-labs +;reporting_distributor = grafana-labs + +# Set to false to disable all checks to https://grafana.net +# for new versions (grafana itself and plugins), check is used +# in some UI views to notify that grafana or plugin update exists +# This option does not cause any auto updates, nor send any information +# only a GET request to http://grafana.com to get latest versions +;check_for_updates = true + +# Google Analytics universal tracking code, only enabled if you specify an id here +;google_analytics_ua_id = + +# Google Tag Manager ID, only enabled if you specify an id here +;google_tag_manager_id = + +#################################### Security #################################### +[security] +# disable creation of admin user on first start of grafana +;disable_initial_admin_creation = false + +# default admin user, created on startup +;admin_user = admin + +# default admin password, can be changed before first start of grafana, or in profile settings +;admin_password = admin + +# used for signing +;secret_key = SW2YcwTIb9zpOOhoPsMm + +# disable gravatar profile images +;disable_gravatar = false + +# data source proxy whitelist (ip_or_domain:port separated by spaces) +;data_source_proxy_whitelist = + +# disable protection against brute force login attempts +;disable_brute_force_login_protection = false + +# set to true if you host Grafana behind HTTPS. default is false. +;cookie_secure = false + +# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled" +;cookie_samesite = lax + +# set to true if you want to allow browsers to render Grafana in a ,