├── .github
├── CODEOWNERS
└── workflows
│ ├── chart-lint-test.yml
│ ├── fossa.yml
│ ├── jsonnet-lint.yml
│ └── release-charts.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── RELEASE.md
├── SECURITY.md
├── SECURITY_CONTACTS.md
├── contribute
├── alerts.md
├── dashboards.md
├── design.md
├── images
│ └── openebs-monitoring.png
├── release.md
└── service-monitor.md
├── ct.yml
├── deploy
└── charts
│ ├── .helmignore
│ ├── Chart.yaml
│ ├── README.md
│ ├── dashboards
│ ├── lvmLocalPV
│ │ └── lvmlocalpv-pool.json
│ ├── mayastor
│ │ ├── mayastor-diskpool.json
│ │ ├── mayastor-volume-replica.json
│ │ └── mayastor-volume.json
│ ├── npd
│ │ └── npd-node-volume-problem.json
│ └── zfsLocalPV
│ │ └── zfslocalpv.json
│ ├── rules
│ ├── lvmLocalPV
│ │ └── lvmlocalpv-rules.json
│ ├── npd
│ │ └── npd-rules.json
│ └── volume
│ │ └── volume-rules.json
│ ├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── dashboards-json-configmap.yaml
│ ├── podmonitors.yaml
│ ├── prometheusRules.yaml
│ └── servicemonitors.yaml
│ └── values.yaml
├── docs
├── extends-stack-with-umbrella-chart.md
├── guide.md
├── metrics-csi.md
├── metrics-lvm.md
├── metrics-node-exporter.md
├── metrics-node-problem-detector.md
└── openebs-mixin-user-guide.md
├── jsonnet
├── Makefile
├── buildscripts
│ ├── go.mod
│ ├── go.sum
│ └── tools.go
└── openebs-mixin
│ ├── Makefile
│ ├── README.md
│ ├── build.sh
│ ├── config.libsonnet
│ ├── dashboards
│ ├── dashboards.libsonnet
│ ├── mayastor
│ │ ├── mayastor-diskpool.json
│ │ ├── mayastor-volume-replica.json
│ │ └── mayastor-volume.json
│ ├── npd
│ │ └── npd-node-volume-problem.json
│ └── openebs
│ │ ├── lvmlocalpv-pool.json
│ │ └── zfslocalpv.json
│ ├── jsonnetfile.json
│ ├── lib
│ ├── dashboards.jsonnet
│ └── rules.jsonnet
│ ├── mixin.libsonnet
│ └── rules
│ ├── npd
│ └── npd-rules.libsonnet
│ ├── openebs
│ └── lvmlocalpv-rules.libsonnet
│ ├── prometheus-rules.libsonnet
│ ├── rules.libsonnet
│ └── volume
│ └── volume-rules.libsonnet
├── nix
├── README.md
├── lib
│ ├── rust.nix
│ └── sourcer.nix
├── overlay.nix
├── sources.json
└── sources.nix
└── scripts
├── generate-readme.sh
└── shell.nix
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Default code owners
2 | * @openebs/localpv-hostpath-approvers @openebs/localpv-zfs-approvers @openebs/localpv-lvm-approvers @openebs/mayastor-approvers
3 |
4 | # OEP owners
5 | /designs @openebs/org-maintainers
6 |
7 | # CODEOWNERS file owners
8 | /.github/CODEOWNERS @openebs/org-maintainers
9 |
10 | # Policy docs owners
11 | /CODE_OF_CONDUCT.md @openebs/org-maintainers
12 | /CONTRIBUTING.md @openebs/org-maintainers
13 | /GOVERNANCE.md @openebs/org-maintainers
14 | /LICENSE @openebs/org-maintainers
15 | /MAINTAINERS.md @openebs/org-maintainers
16 | /SECURITY.md @openebs/org-maintainers
17 | /SECURITY_CONTACTS.md @openebs/org-maintainers
18 |
--------------------------------------------------------------------------------
/.github/workflows/chart-lint-test.yml:
--------------------------------------------------------------------------------
1 | name: Chart Lint and Test
2 |
3 | on:
4 | push:
5 | paths:
6 | - 'deploy/charts/**'
7 | branches:
8 | - develop
9 | pull_request:
10 | paths:
11 | - 'deploy/charts/**'
12 | branches:
13 | - develop
14 |
15 | jobs:
16 | lint-test:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 |
24 | - name: Set up Helm
25 | uses: azure/setup-helm@v4
26 | with:
27 | version: v3.14.3
28 |
29 | - uses: actions/setup-python@v5
30 | with:
31 | python-version: '3.10'
32 | check-latest: true
33 |
34 | - name: Set up chart-testing
35 | uses: helm/chart-testing-action@v2.6.1
36 |
37 | - name: Run chart-testing (list-changed)
38 | id: list-changed
39 | run: |
40 | changed=$(ct list-changed --config ct.yml)
41 | if [[ -n "$changed" ]]; then
42 | echo "changed=true" >> $GITHUB_OUTPUT
43 | fi
44 |
45 | - name: Run chart-testing (lint)
46 | run: ct lint --config ct.yml
47 |
48 | - name: Create kind cluster
49 | uses: helm/kind-action@v1.9.0
50 | if: steps.list-changed.outputs.changed == 'true'
51 |
52 | - name: Run chart-testing (install)
53 | run: ct install --config ct.yml
54 |
--------------------------------------------------------------------------------
/.github/workflows/fossa.yml:
--------------------------------------------------------------------------------
1 | name: Fossa CLI
2 | on:
3 | push:
4 | branches:
5 | - 'develop'
6 |
7 | jobs:
8 | fossa-scan:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | with:
13 | submodules: recursive
14 | - uses: fossas/fossa-action@v1.4.0
15 | with:
16 | api-key: ${{ secrets.FOSSA_API_KEY }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/jsonnet-lint.yml:
--------------------------------------------------------------------------------
1 | name: Jsonnet lint
2 |
3 | on:
4 | push:
5 | paths:
6 | - "jsonnet/**"
7 | branches:
8 | - develop
9 | pull_request:
10 | paths:
11 | - "jsonnet/**"
12 | branches:
13 | - develop
14 |
15 | jobs:
16 | lint:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 |
24 | - name: Jsonnet formatter and linter
25 | run: |
26 | cd jsonnet && make --always-make all
27 |
28 |
--------------------------------------------------------------------------------
/.github/workflows/release-charts.yml:
--------------------------------------------------------------------------------
1 | name: Release Charts
2 |
3 | on:
4 | push:
5 | paths:
6 | - "deploy/charts/**"
7 | branches:
8 | - develop
9 |
10 | jobs:
11 | release:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 |
19 | - name: Configure Git
20 | run: |
21 | git config user.name "$GITHUB_ACTOR"
22 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
23 |
24 | - name: Install Helm
25 | uses: azure/setup-helm@v4
26 | with:
27 | version: v3.14.3
28 |
29 | - name: Add dependency chart repos
30 | run: |
31 | helm repo add kube-prometheus-stack https://prometheus-community.github.io/helm-charts
32 | helm repo add node-problem-detector https://charts.deliveryhero.io/
33 | helm repo add localpv-provisioner https://openebs.github.io/dynamic-localpv-provisioner
34 |
35 | - name: Run chart-releaser
36 | uses: helm/chart-releaser-action@v1.6.0
37 | env:
38 | CR_TOKEN: "${{ secrets.CR_TOKEN }}"
39 | with:
40 | charts_dir: deploy
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Chart dependencies
2 | /deploy/charts/charts
3 | /deploy/charts/Chart.lock
4 |
5 | # ide
6 | **/.idea
7 |
8 | jsonnet/vendor/
9 | jsonnet/tmp/
10 | jsonnet/buildscripts/vendor/
11 | jsonnet/manifests
12 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 |
4 | ## Umbrella Project
5 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
6 |
7 |
8 | This project follows the [OpenEBS Code of Conduct](https://github.com/openebs/community/blob/HEAD/CODE_OF_CONDUCT.md)
9 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 |
4 | ## Umbrella Project
5 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
6 |
7 |
8 | This project follows the [OpenEBS Contributor Guidelines](https://github.com/openebs/community/blob/HEAD/CONTRIBUTING.md)
9 |
10 | # Contributing
11 |
12 | OpenEBS uses the standard GitHub pull requests process to review and accept contributions. There are several areas that could use your help. For starters, you could help in improving the sections in this document by either creating a new issue describing the improvement or submitting a pull request to this repository. The issues for the various OpenEBS components (including components in this repository) are maintained in [openebs/openebs](https://github.com/openebs/openebs/issues) repository.
13 |
14 | * If you have a trivial fix or improvement, go ahead and create a pull request, addressing (with `@...`) the maintainer of this repository (see [MAINTAINERS](MAINTAINERS)) in the description of the pull request.
15 |
16 | * If you would like to work on something more involved, please connect with the OpenEBS Contributors. See [OpenEBS Community](https://github.com/openebs/openebs/tree/master/community).
17 |
18 | ## Steps to Contribute
19 |
20 | OpenEBS is an Apache 2.0 Licensed project and all your commits should be signed with Developer Certificate of Origin. See [Sign your work](#sign-your-work).
21 |
22 | * Find an issue to work on or create a new issue. The issues are maintained at [openebs/openebs](https://github.com/openebs/openebs/issues). You can pick up from a list of [good-first-issues](https://github.com/openebs/openebs/labels/good%20first%20issue).
23 | * Claim your issue by commenting your intent to work on it to avoid duplication of efforts.
24 | * Fork the repository on GitHub.
25 | * Create a branch from where you want to base your work (usually master).
26 | * Make your changes.
27 | * Commit your changes by making sure the commit messages convey the need and notes about the commit.
28 | * Push your changes to the branch in your fork of the repository.
29 | * Submit a pull request to the original repository. See [Pull Request checklist](#pull-request-checklist).
30 |
31 | ## Pull Request Checklist
32 |
33 | * Rebase to the current master branch before submitting your pull request.
34 | * Commits should be as small as possible. Each commit should follow the checklist below:
35 | - For code changes, add tests relevant to the fixed bug or new feature.
36 | - Pass the compile and tests - includes spell checks, formatting, etc.
37 | - Commit header (first line) should convey what changed.
38 | - Commit body should include details such as why the changes are required and how the proposed changes.
39 | - DCO Signed.
40 | * If your PR is not getting reviewed or you need a specific person to review it, please reach out to the OpenEBS Contributors. See [OpenEBS Community](https://github.com/openebs/openebs/tree/master/community).
41 |
42 | ## Sign your work
43 |
44 | We use the Developer Certificate of Origin (DCO) as an additional safeguard for the OpenEBS project. This is a well established and widely used mechanism to assure that contributors have confirmed their right to license their contribution under the project's license. Please read [dcofile](https://github.com/openebs/openebs/blob/master/contribute/developer-certificate-of-origin). If you can certify it, then just add a line to every git commit message:
45 |
46 | ```
47 | Signed-off-by: Random J Developer
48 | ```
49 |
50 | Use your real name (sorry, no pseudonyms or anonymous contributions). The email id should match the email id provided in your GitHub profile.
51 | If you set your `user.name` and `user.email` in git config, you can sign your commit automatically with `git commit -s`.
52 |
53 | You can also use git [aliases](https://git-scm.com/book/tr/v2/Git-Basics-Git-Aliases) like `git config --global alias.ci 'commit -s'`. Now you can commit with `git ci` and the commit will be signed.
54 |
55 |
--------------------------------------------------------------------------------
/GOVERNANCE.md:
--------------------------------------------------------------------------------
1 | # Governance
2 |
3 |
4 | ## Umbrella Project
5 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
6 |
7 |
8 | This project follows the [OpenEBS Governance](https://github.com/openebs/community/blob/HEAD/GOVERNANCE.md)
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
1 | # Maintainers
2 |
3 |
4 |
5 | ## Umbrella Project
6 |
7 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
8 |
9 |
10 | Please refer to the [OpenEBS Maintainers](https://github.com/openebs/community/blob/HEAD/MAINTAINERS.md).
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenEBS Monitoring add-on
2 |
3 | [](https://kubernetes.slack.com/messages/openebs)
4 | [](https://github.com/openebs/community/blob/HEAD/README.md#community)
5 | [](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopenebs%2Fmonitoring?ref=badge_shield&issueType=license)
6 |
7 |
8 | A set of Grafana dashboards and Prometheus alerts for OpenEBS that can be installed as a [helm chart](./deploy/charts/) or imported as [jsonnet mixin](./jsonnet/).
9 |
10 | ## Status
11 |
12 | **Beta**. This repository currently supports dashboards and alerts for `Mayastor`, `LocalPV LVM`, `LocalPV ZFS` OpenEBS storage engines.
13 | This project is under active development and seeking [contributions from the community](#contributing).
14 |
15 |
16 | ## Install
17 |
18 | ### Using helm
19 |
20 | Setup the monitoring helm repository.
21 |
22 | ```console
23 | helm repo add monitoring https://openebs.github.io/monitoring/
24 | helm repo update
25 | ```
26 |
27 | You can then run `helm search repo monitoring` to see the charts.
28 |
29 | Install the helm chart.
30 | ```
31 | helm install monitoring monitoring/monitoring --namespace openebs --create-namespace
32 | ```
33 |
34 | The detailed chart documentation is available in [charts directory](/deploy/charts/README.md).
35 |
36 | ### Using kubectl
37 |
38 | You can generate YAMLs and install using kubectl. See detailed steps at [./jsonnet](/jsonnet/README.md).
39 |
40 | ## Usage
41 |
42 | ### Accessing Grafana
43 |
44 | ```console
45 | # Look at the Grafana pod and check that the pod is in running state
46 | kubectl get pods -n [NAMESPACE] | grep -i grafana
47 | # Note the public IP of any one of the nodes
48 | kubectl get nodes -o wide
49 | # Note the Grafana Service IP
50 | kubectl get svc -n [NAMESPACE] | grep -i grafana
51 | # Open browser and visit http://:
52 | # (where is the public IP address of your node, and is Grafana Service Port)
53 | # Default Grafana login credentials- [username: admin, password: admin]
54 | ```
55 |
56 | **NOTE:** If public IP is not available then you can access it via port-forwarding
57 |
58 | ```console
59 | # Perform port-forwarding
60 | # kubectl port-forward --namespace [NAMESPACE] pods/[grafana-pod-name] [grafrana-foward-port]:[grafana-cluster-port]
61 | # Open browser and visit http://127.0.0.1:[grafana-forward-port]
62 | # Default Grafana login credentials- [username: admin, password: admin]
63 | ```
64 |
65 |
66 | ## Contributing
67 |
68 | OpenEBS welcomes your feedback and contributions in any form possible.
69 |
70 | - Want to raise an issue or help with fixes and features?
71 | - See [open issues](https://github.com/openebs/monitoring/issues)
72 | - See [Project Roadmap](https://github.com/orgs/openebs/projects/41)
73 | - See [contributing guide](./CONTRIBUTING.md)
74 |
75 | ## Community
76 |
77 | - [Join OpenEBS community on Kubernetes Slack](https://kubernetes.slack.com)
78 | - Already signed up? Head to our discussions at [#openebs](https://kubernetes.slack.com/messages/openebs/)
79 | - Want to join our contributor community meetings, [check this out](https://github.com/openebs/openebs/blob/HEAD/community/README.md).
80 | - Join our OpenEBS CNCF Mailing lists
81 | - For OpenEBS project updates, subscribe to [OpenEBS Announcements](https://lists.cncf.io/g/cncf-openebs-announcements)
82 | - For interacting with other OpenEBS users, subscribe to [OpenEBS Users](https://lists.cncf.io/g/cncf-openebs-users)
83 |
84 | ## Code of conduct
85 |
86 | Participation in the OpenEBS community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/HEAD/code-of-conduct.md).
87 |
88 |
89 | ## License Compliance
90 | [](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopenebs%2Fmonitoring?ref=badge_large&issueType=license)
91 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | This is a OpenEBS sub project and abides by the
2 | [OpenEBS Release Process](https://github.com/openebs/openebs/blob/master/RELEASE.md).
3 |
4 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 |
4 |
5 | ## Umbrella Project
6 |
7 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
8 |
9 |
10 | This project follows the [OpenEBS Security Policy](https://github.com/openebs/community/blob/HEAD/SECURITY.md).
11 |
--------------------------------------------------------------------------------
/SECURITY_CONTACTS.md:
--------------------------------------------------------------------------------
1 | # Security Contacts
2 |
3 |
4 |
5 | ## Umbrella Project
6 |
7 | OpenEBS is an "umbrella project". Every project, repository and file in the OpenEBS organization adopts and follows the policies found in the Community repo umbrella project files.
8 |
9 |
10 | Please refer to the [OpenEBS Security Contacts](https://github.com/openebs/community/blob/HEAD/SECURITY_CONTACTS.md).
11 |
--------------------------------------------------------------------------------
/contribute/alerts.md:
--------------------------------------------------------------------------------
1 | ## How to add new alerts in openebs-mixin.
2 | To add new alert rules in openebs-mixin, you need to add alert rules in [rules](jsonnet/../../jsonnet/openebs-mixin/rules/) directory and import it through [rules.libsonnet](../jsonnet/openebs-mixin/dashboards/dashboards.libsonnet)and [prometheus-rules.libsonnet](../jsonnet/openebs-mixin/rules/prometheus-rules.libsonnet) to include it in prometheusRules object.
3 |
4 | ## Step by Step Process
5 | 1. Add alert rules in [rules](jsonnet/../../jsonnet/openebs-mixin/rules/) directory.
6 | - **new-alert-rules.libsonnet**
7 | ```
8 | function(param) {
9 | //local rules = self,
10 | _config+:: param,
11 | prometheusRules+:: {
12 | npd: {
13 | groups+: [
14 | {
15 | name: 'volume-node',
16 | rules: [
17 | {
18 | alert-rule 1
19 | }
20 | . . .
21 | ]
22 | }]
23 | }
24 | }
25 | };
26 | ```
27 |
28 | 2. Add configuration in [config.libsonnet](../jsonnet/openebs-mixin/config.libsonnet) to allow users to configure alert rules. For example:
29 | ```
30 | . . .
31 | // // AlertRules configuration. If set, then alert rules are included in the prometheusRules object.
32 | alertRules: {
33 | newAlertRules: true # to include alert rules in prometheusRules object
34 | },
35 | . . .
36 | ```
37 | 3. Import the alert rules in [rules.libsonnet](../jsonnet/openebs-mixin/dashboards/dashboards.libsonnet) and [prometheus-rules.libsonnet](../jsonnet/openebs-mixin/rules/prometheus-rules.libsonnet) and include it in `prometheusRules` object.
38 | Examples:
39 | - [**prometheus-rules.libsonnet**](../jsonnet/openebs-mixin/rules/prometheus-rules.libsonnet)
40 | ```
41 | . . .
42 | local newAlertRules = (import './new-alert-rules.libsonnet');
43 |
44 | prometheusRules+::
45 | . . .
46 | + newAlertRules(prometheusRules._config).prometheusRules.newAlertRules,
47 | . . .
48 | ```
49 | - [**rules.libsonnet**](../jsonnet/openebs-mixin/dashboards/dashboards.libsonnet)
50 | ```
51 | . . .
52 | local newAlertRules = (import './new-alert-rules.libsonnet');
53 |
54 | prometheusRules+::
55 | . . .
56 | + newAlertRules(prometheusRules._config).prometheusRules.newAlertRules.groups,
57 | . . .
58 | ```
--------------------------------------------------------------------------------
/contribute/dashboards.md:
--------------------------------------------------------------------------------
1 | ## How to add new dashboards in openebs-mixin.
2 | To add new dashboard in openebs-mixin, you need to add dashboard json file in [dashboards](jsonnet/../../jsonnet/openebs-mixin/dashboards/) directory and import it through [dashboards.libsonnet](../jsonnet/openebs-mixin/dashboards/dashboards.libsonnet) to create grafanaDashboards object.
3 |
4 | ## Step by Step Process
5 | 1. Add dashboards json in [dashboards](jsonnet/../../jsonnet/openebs-mixin/dashboards/) directory.
6 | 2. Add configuration in [config.libsonnet](../jsonnet/openebs-mixin/config.libsonnet) to allow users to configure dashboard. For example:
7 | ```
8 | . . .
9 | // dashboards configuration. If set, then dashboards are included in grafanaDashboards object.
10 | dashboards: {
11 | newDashboard: true # to import dashboard as grafanaDashboards object
12 | },
13 | . . .
14 | ```
15 | 3. Import the dashboard json in [dashboards.libsonnet](../jsonnet/openebs-mixin/dashboards/dashboards.libsonnet) to include it in `grafanaDashboards` object.
16 | ```
17 | . . .
18 | grafanaDashboards+:: {
19 | . . .
20 | [if dashboard._config.dashboards.newDashboard then 'new-dashboard.json']: import './new-dashboard.json',
21 | },
22 | . . .
23 | ```
--------------------------------------------------------------------------------
/contribute/design.md:
--------------------------------------------------------------------------------
1 | # openEBS Monitoring
2 |
3 | 
4 |
5 | OpenEBS monitoring written in jsonnet has two components:
6 | 1. [**kube-prometheus stack**](https://github.com/prometheus-operator/kube-prometheus/tree/main/jsonnet/kube-prometheus)
7 | It is a monitoring stack which includes prometheus, grafana and alertmanager.
8 | 2. [**openebs-mixin**](https://github.com/openebs/monitoring/tree/develop/jsonnet/openebs-mixin)
9 | It is a mixin for openebs. It includes all the dashboards and alert rules for different cas types of openebs which are used to import grafanaDashboards and create prometheusRules objects.
10 |
11 | ## Directory structure
12 |
13 | - OpenEBS Monitoring
14 |
15 | ```
16 | jsonnet
17 | ├── addons # monitoring addon
18 | │ ├── podMonitors.libsonnet # podMonitor to be created for different cas types
19 | │ ├── prometheusRules.libsonnet # create prometheusRule object which includes alert rules defined in openebs-mixin
20 | │ └── serviceMonitors.libsonnet # serviceMonitor to be created for different cas types
21 | |
22 | ├── config.libsonnet # configuration to be used for openebs monitoing
23 | |
24 | ├── jsonnetfile.json # direct dependencies
25 | ├── jsonnetfile.lock.json # all dependencies with exact version
26 | |
27 | ├── lib # contains code that is used in different places
28 | │ └── utils.libsonnet # code which is used to create monitoring addons
29 | |
30 | ├── main.jsonnet # entrypoint of code(openEBS Monitoring)
31 | ├── Makefile
32 | |
33 | └── openebs-mixin # contains grafanaDashboards and prometheusRules
34 |
35 | ```
36 |
37 | - openebs-mixin
38 |
39 |
40 | ```
41 | openebs-mixin # openebs-mixin for grafanaDashboards and prometheusRules.
42 | ├── build.sh
43 | ├── config.libsonnet # configuration that is used while writing dashboards and alert rules
44 | ├── dashboards
45 | │ ├── openebs/
46 | │ ├── . . .
47 | │ ├── dashboards.libsonnet # to import all the dashboard json through grafanaDashboards object.
48 | |
49 | ├── jsonnetfile.json # direct dependencies
50 | |
51 | ├── lib
52 | │ ├── dashboards.jsonnet # to generate dashboards for helm charts
53 | │ └── rules.jsonnet # to generate alert rules for helm charts
54 | |
55 | ├── Makefile
56 | |
57 | ├── mixin.libsonnet # openebs-mixin that imports grafanaDashboards and prometheusRules
58 | |
59 | └── rules # contains alert rules for different cas types
60 | ├── openebs/
61 | ├── . . .
62 | ├── rules.libsonnet # used in openebs monitoring
63 | └── prometheus-rules.libsonnet # to create prometheusRules object
64 | ```
--------------------------------------------------------------------------------
/contribute/images/openebs-monitoring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openebs/monitoring/f0867a43571008ac2ecfbe5d2d95e24ea0ada9a2/contribute/images/openebs-monitoring.png
--------------------------------------------------------------------------------
/contribute/release.md:
--------------------------------------------------------------------------------
1 | ## How to generate dashboards and alert rules for monitoring helm chart
2 |
3 | To generate dashboards and alert rules for monitoring helm chart and release a new version of helm chart.
4 |
5 | ## Step by Step Process
6 | 1. Add [dashboards](dashboards.md) and [alerts rules](alerts.md) in openebs-mixin by following the documented steps.
7 |
8 | 2. Update the dashboards and rules folder in [build.sh](../jsonnet/openebs-mixin/build.sh). The auto generated json files will be inside this folder.
9 |
10 | For example: If you add dashboards and alert rules for Mayastor in openebs-mixin, then add mayastor as a folder name in build.sh file.
11 | ```
12 | generateDashboards(){
13 | . . .
14 | dashboardsFolder=(npd lvmLocalPV zfsLocalPV mayastor)
15 | . . .
16 | }
17 |
18 | generateRules(){
19 | . . .
20 | rulesFolder=(npd lvmLocalPV zfsLocalPV mayastor)
21 | . . .
22 | }
23 | ```
24 | 3. Run `make generate` to generate the dashboards and alert rules for the monitoring helm chart.
25 | ```
26 | $ cd jsonnet/openebs-mixin
27 | $ make generate
28 | ```
29 |
30 | 4. Update [helm configurations](../deploy/charts/values.yaml).
31 |
32 | For example: Add mayastor configuration in values.yaml with the following fields.
33 | ```
34 | . . .
35 | openebsMonitoringAddon:
36 | mayastor:
37 | enabled: true
38 | dashboards:
39 | enabled: true
40 | alertRules:
41 | enabled: true
42 | . . .
43 | ```
44 |
45 | 5. Update chart version in [chart.yaml](../deploy/charts/Chart.yaml)
46 | ```
47 | . . .
48 | version: 0.4.x
49 | . . .
50 | ```
51 |
52 | ---
53 | **NOTE**
54 |
55 | - To upgrade the depdendencies like kube-prometheus, do `jb update`.
56 | ```
57 | cd jsonnet
58 | jb update
59 | ```
60 |
61 | - To upgrade the dependencies like kube-prometheus-stack in helm chart, update its version in [chart.yaml](../deploy/charts/Chart.yaml)
62 | ```
63 | . . .
64 | dependencies:
65 | - name: kube-prometheus-stack
66 | version: "16.5.*"
67 | . . .
68 | ```
69 |
--------------------------------------------------------------------------------
/contribute/service-monitor.md:
--------------------------------------------------------------------------------
1 | ## How to add new serviceMonitor for a CAS type.
2 | To add serviceMonitor, you only need to add configuration in [config.libsonnet](jsonnet/../../jsonnet/config.libsonnet).
3 |
4 | Example:
5 | - To add serviceMonitor for mayastor:
6 | ```
7 | . . .
8 | _config+:: {
9 | . . .
10 | // Configuration for different cas types.
11 | openebsMonitoringAddon: {
12 | mayastor: {
13 | serviceMonitor: serviceMonitor(, , ) {
14 | enabled: true,
15 | endpoints+: {
16 | . . .
17 | }
18 | }
19 | }
20 | }
21 | }
22 | . . .
23 | ```
--------------------------------------------------------------------------------
/ct.yml:
--------------------------------------------------------------------------------
1 | # See https://github.com/helm/chart-testing#configuration
2 | remote: origin
3 | target-branch: develop
4 | chart-dirs:
5 | - deploy
6 | chart-repos:
7 | - kube-prometheus-stack=https://prometheus-community.github.io/helm-charts
8 | - node-problem-detector=https://charts.deliveryhero.io/
9 | - localpv-provisioner=https://openebs.github.io/dynamic-localpv-provisioner
10 | helm-extra-args: --timeout=500s
11 | validate-maintainers: false
12 |
--------------------------------------------------------------------------------
/deploy/charts/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *.orig
18 | *~
19 | # Various IDEs
20 | .project
21 | .idea/
22 | *.tmproj
23 | .vscode/
24 |
--------------------------------------------------------------------------------
/deploy/charts/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v2
2 | name: monitoring
3 | description: A Helm chart for monitoring OpenEBS
4 |
5 | # A chart can be either an 'application' or a 'library' chart.
6 | #
7 | # Application charts are a collection of templates that can be packaged into versioned archives
8 | # to be deployed.
9 | #
10 | # Library charts provide useful utilities or functions for the chart developer. They're included as
11 | # a dependency of application charts to inject those utilities and functions into the rendering
12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed.
13 | type: application
14 |
15 | sources:
16 | - https://github.com/openebs/monitoring
17 |
18 | keywords:
19 | - openebs
20 | - monitoring
21 |
22 | # This is the chart version. This version number should be incremented each time you make changes
23 | # to the chart and its templates, including the app version.
24 | # Versions are expected to follow Semantic Versioning (https://semver.org/)
25 | version: 4.0.1
26 |
27 | # This is the version number of the application being deployed. This version number should be
28 | # incremented each time you make changes to the application. Versions are not expected to
29 | # follow Semantic Versioning. They should reflect the version the application is using.
30 | appVersion: 4.0.1
31 |
32 | dependencies:
33 | - name: kube-prometheus-stack
34 | version: "61.0.*"
35 | repository: https://prometheus-community.github.io/helm-charts
36 | condition: kube-prometheus-stack.install
37 | - name: node-problem-detector
38 | version: "2.0.*"
39 | repository: https://charts.deliveryhero.io/
40 | condition: node-problem-detector.install
41 | - name: localpv-provisioner
42 | version: 4.1.0
43 | repository: https://openebs.github.io/dynamic-localpv-provisioner
44 | condition: localpv-provisioner.enabled
45 |
--------------------------------------------------------------------------------
/deploy/charts/README.md:
--------------------------------------------------------------------------------
1 | # monitoring
2 |
3 |   
4 |
5 | A Helm chart for monitoring OpenEBS
6 |
7 | ## Source Code
8 |
9 | *
10 |
11 | ## Requirements
12 |
13 | | Repository | Name | Version |
14 | |------------|------|---------|
15 | | https://charts.deliveryhero.io/ | node-problem-detector | 2.0.* |
16 | | https://openebs.github.io/dynamic-localpv-provisioner | localpv-provisioner | 4.1.0 |
17 | | https://prometheus-community.github.io/helm-charts | kube-prometheus-stack | 61.0.* |
18 |
19 | ## Values
20 |
21 | | Key | Type | Default | Description |
22 | |-----|------|---------|-------------|
23 | | fullnameOverride | string | `""` | |
24 | | kube-prometheus-stack.alertmanager.alertmanagerSpec.replicas | int | `1` | |
25 | | kube-prometheus-stack.alertmanager.alertmanagerSpec.storage | object | `{}` | |
26 | | kube-prometheus-stack.alertmanager.config.global.resolve_timeout | string | `"5m"` | |
27 | | kube-prometheus-stack.alertmanager.config.receivers[0].name | string | `"null"` | |
28 | | kube-prometheus-stack.alertmanager.config.route.group_by[0] | string | `"alertname"` | |
29 | | kube-prometheus-stack.alertmanager.config.route.group_by[1] | string | `"job"` | |
30 | | kube-prometheus-stack.alertmanager.config.route.group_by[2] | string | `"volName"` | |
31 | | kube-prometheus-stack.alertmanager.config.route.group_interval | string | `"5m"` | |
32 | | kube-prometheus-stack.alertmanager.config.route.group_wait | string | `"30s"` | |
33 | | kube-prometheus-stack.alertmanager.config.route.receiver | string | `"null"` | |
34 | | kube-prometheus-stack.alertmanager.config.route.repeat_interval | string | `"4h"` | |
35 | | kube-prometheus-stack.alertmanager.config.route.routes[0].matchers[0] | string | `"product=\"openebs\""` | |
36 | | kube-prometheus-stack.alertmanager.config.route.routes[0].receiver | string | `"null"` | |
37 | | kube-prometheus-stack.alertmanager.config.templates[0] | string | `"/etc/alertmanager/config/*.tmpl"` | |
38 | | kube-prometheus-stack.alertmanager.enabled | bool | `true` | |
39 | | kube-prometheus-stack.alertmanager.service.nodePort | int | `30903` | |
40 | | kube-prometheus-stack.alertmanager.service.type | string | `"NodePort"` | |
41 | | kube-prometheus-stack.global.rbac.pspEnabled | bool | `false` | |
42 | | kube-prometheus-stack.grafana."grafana.ini".panels.disable_sanitize_html | bool | `true` | |
43 | | kube-prometheus-stack.grafana.adminPassword | string | `"admin"` | |
44 | | kube-prometheus-stack.grafana.defaultDashboardsEnabled | bool | `true` | |
45 | | kube-prometheus-stack.grafana.enabled | bool | `true` | |
46 | | kube-prometheus-stack.grafana.persistence.accessModes[0] | string | `"ReadWriteOnce"` | |
47 | | kube-prometheus-stack.grafana.persistence.enabled | bool | `true` | |
48 | | kube-prometheus-stack.grafana.persistence.size | string | `"1Gi"` | |
49 | | kube-prometheus-stack.grafana.persistence.storageClassName | string | `"openebs-hostpath"` | |
50 | | kube-prometheus-stack.grafana.plugins[0] | string | `"grafana-polystat-panel"` | |
51 | | kube-prometheus-stack.grafana.plugins[1] | string | `"snuids-trafficlights-panel"` | |
52 | | kube-prometheus-stack.grafana.rbac.pspEnabled | bool | `false` | |
53 | | kube-prometheus-stack.grafana.service.nodePort | int | `32515` | |
54 | | kube-prometheus-stack.grafana.service.type | string | `"NodePort"` | |
55 | | kube-prometheus-stack.grafana.sidecar.dashboards.enabled | bool | `true` | |
56 | | kube-prometheus-stack.grafana.sidecar.dashboards.label | string | `"grafana_dashboard"` | |
57 | | kube-prometheus-stack.install | bool | `true` | |
58 | | kube-prometheus-stack.kube-state-metrics.podSecurityPolicy.enabled | bool | `false` | |
59 | | kube-prometheus-stack.prometheus-node-exporter.extraArgs[0] | string | `"--collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+)($|/)"` | |
60 | | kube-prometheus-stack.prometheus-node-exporter.extraArgs[1] | string | `"--collector.filesystem.fs-types-exclude=^(tmpfs|autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$"` | |
61 | | kube-prometheus-stack.prometheus-node-exporter.extraArgs[2] | string | `"--collector.diskstats.device-exclude=^(ram|loop|fd|sr|(h|s|v|xv)d[a-z]+|nvme\\d+n\\d+p|nvme\\d+c\\d+n)\\d+$"` | |
62 | | kube-prometheus-stack.prometheus-node-exporter.rbac.pspEnabled | bool | `false` | |
63 | | kube-prometheus-stack.prometheus-node-exporter.securityContext.fsGroup | int | `65534` | |
64 | | kube-prometheus-stack.prometheus-node-exporter.securityContext.runAsGroup | int | `0` | |
65 | | kube-prometheus-stack.prometheus-node-exporter.securityContext.runAsNonRoot | bool | `false` | |
66 | | kube-prometheus-stack.prometheus-node-exporter.securityContext.runAsUser | int | `0` | |
67 | | kube-prometheus-stack.prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues | bool | `false` | |
68 | | kube-prometheus-stack.prometheus.prometheusSpec.replicas | int | `1` | |
69 | | kube-prometheus-stack.prometheus.prometheusSpec.ruleSelectorNilUsesHelmValues | bool | `false` | |
70 | | kube-prometheus-stack.prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues | bool | `false` | |
71 | | kube-prometheus-stack.prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.metadata.name | string | `"openebs-prometheus-pv"` | |
72 | | kube-prometheus-stack.prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.accessModes[0] | string | `"ReadWriteOnce"` | |
73 | | kube-prometheus-stack.prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage | string | `"1Gi"` | |
74 | | kube-prometheus-stack.prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName | string | `"openebs-hostpath"` | |
75 | | kube-prometheus-stack.prometheus.service.nodePort | int | `32514` | |
76 | | kube-prometheus-stack.prometheus.service.type | string | `"NodePort"` | |
77 | | kube-prometheus-stack.prometheusOperator.enabled | bool | `true` | |
78 | | localpv-provisioner.analytics.enabled | bool | `true` | |
79 | | localpv-provisioner.enabled | bool | `true` | |
80 | | localpv-provisioner.hostpathClass.enabled | bool | `true` | Enable default hostpath localpv StorageClass. |
81 | | localpv-provisioner.hostpathClass.name | string | `"openebs-hostpath"` | |
82 | | nameOverride | string | `""` | |
83 | | namespaceOverride | string | `""` | |
84 | | node-problem-detector.extraVolumeMounts[0].mountPath | string | `"/dev/kmsg"` | |
85 | | node-problem-detector.extraVolumeMounts[0].name | string | `"kmsg"` | |
86 | | node-problem-detector.extraVolumeMounts[0].readOnly | bool | `true` | |
87 | | node-problem-detector.extraVolumes[0].hostPath.path | string | `"/dev/kmsg"` | |
88 | | node-problem-detector.extraVolumes[0].name | string | `"kmsg"` | |
89 | | node-problem-detector.install | bool | `false` | |
90 | | node-problem-detector.metrics.serviceMonitor.enabled | bool | `true` | |
91 | | openebsMonitoringAddon.lvmLocalPV.alertRules.enabled | bool | `true` | |
92 | | openebsMonitoringAddon.lvmLocalPV.dashboards.enabled | bool | `true` | |
93 | | openebsMonitoringAddon.lvmLocalPV.enabled | bool | `true` | |
94 | | openebsMonitoringAddon.lvmLocalPV.serviceMonitor.enabled | bool | `true` | |
95 | | openebsMonitoringAddon.lvmLocalPV.serviceMonitor.endpoints.path | string | `"/metrics"` | |
96 | | openebsMonitoringAddon.lvmLocalPV.serviceMonitor.endpoints.port | string | `"metrics"` | |
97 | | openebsMonitoringAddon.lvmLocalPV.serviceMonitor.namespaceSelector.any | bool | `true` | |
98 | | openebsMonitoringAddon.lvmLocalPV.serviceMonitor.selector.matchLabels.name | string | `"openebs-lvm-node"` | |
99 | | openebsMonitoringAddon.mayastor.dashboards.enabled | bool | `true` | |
100 | | openebsMonitoringAddon.mayastor.enabled | bool | `true` | |
101 | | openebsMonitoringAddon.mayastor.serviceMonitor.enabled | bool | `true` | |
102 | | openebsMonitoringAddon.mayastor.serviceMonitor.endpoints.path | string | `"/metrics"` | |
103 | | openebsMonitoringAddon.mayastor.serviceMonitor.endpoints.port | string | `"metrics"` | |
104 | | openebsMonitoringAddon.mayastor.serviceMonitor.namespaceSelector.any | bool | `true` | |
105 | | openebsMonitoringAddon.mayastor.serviceMonitor.selector.matchLabels.app | string | `"metrics-exporter-io-engine"` | |
106 | | openebsMonitoringAddon.npd.alertRules.enabled | bool | `false` | |
107 | | openebsMonitoringAddon.npd.dashboards.enabled | bool | `false` | |
108 | | openebsMonitoringAddon.npd.enabled | bool | `false` | |
109 | | openebsMonitoringAddon.volume.alertRules.enabled | bool | `true` | |
110 | | openebsMonitoringAddon.volume.enabled | bool | `true` | |
111 | | openebsMonitoringAddon.zfsLocalPV.dashboards.enabled | bool | `true` | |
112 | | openebsMonitoringAddon.zfsLocalPV.enabled | bool | `true` | |
113 |
114 | ----------------------------------------------
115 | Autogenerated from chart metadata using [helm-docs vv1.11.0](https://github.com/norwoodj/helm-docs/releases/vv1.11.0)
116 |
--------------------------------------------------------------------------------
/deploy/charts/dashboards/mayastor/mayastor-volume-replica.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "grafana",
8 | "uid": "-- Grafana --"
9 | },
10 | "enable": true,
11 | "hide": true,
12 | "iconColor": "rgba(0, 211, 255, 1)",
13 | "name": "Annotations & Alerts",
14 | "type": "dashboard"
15 | }
16 | ]
17 | },
18 | "editable": true,
19 | "fiscalYearStartMonth": 0,
20 | "graphTooltip": 0,
21 | "id": 43,
22 | "links": [ ],
23 | "panels": [
24 | {
25 | "datasource": {
26 | "type": "prometheus",
27 | "uid": "$datasource"
28 | },
29 | "fieldConfig": {
30 | "defaults": {
31 | "color": {
32 | "mode": "palette-classic"
33 | },
34 | "custom": {
35 | "axisBorderShow": false,
36 | "axisCenteredZero": false,
37 | "axisColorMode": "text",
38 | "axisLabel": "",
39 | "axisPlacement": "auto",
40 | "barAlignment": 0,
41 | "drawStyle": "line",
42 | "fillOpacity": 10,
43 | "gradientMode": "none",
44 | "hideFrom": {
45 | "legend": false,
46 | "tooltip": false,
47 | "viz": false
48 | },
49 | "insertNulls": false,
50 | "lineInterpolation": "linear",
51 | "lineStyle": {
52 | "fill": "solid"
53 | },
54 | "lineWidth": 1,
55 | "pointSize": 5,
56 | "scaleDistribution": {
57 | "type": "linear"
58 | },
59 | "showPoints": "never",
60 | "spanNulls": false,
61 | "stacking": {
62 | "group": "A",
63 | "mode": "none"
64 | },
65 | "thresholdsStyle": {
66 | "mode": "off"
67 | }
68 | },
69 | "mappings": [ ],
70 | "thresholds": {
71 | "mode": "absolute",
72 | "steps": [
73 | {
74 | "color": "green",
75 | "value": null
76 | }
77 | ]
78 | },
79 | "unit": "iops"
80 | },
81 | "overrides": [ ]
82 | },
83 | "gridPos": {
84 | "h": 8,
85 | "w": 12,
86 | "x": 0,
87 | "y": 0
88 | },
89 | "id": 1,
90 | "options": {
91 | "legend": {
92 | "calcs": [ ],
93 | "displayMode": "list",
94 | "placement": "bottom",
95 | "showLegend": true
96 | },
97 | "tooltip": {
98 | "mode": "multi",
99 | "sort": "none"
100 | }
101 | },
102 | "pluginVersion": "10.4.0",
103 | "targets": [
104 | {
105 | "datasource": {
106 | "uid": "$datasource"
107 | },
108 | "editorMode": "code",
109 | "exemplar": false,
110 | "expr": "irate(replica_num_read_ops{name=~\"$replica_name\"}[1m])",
111 | "interval": "",
112 | "legendFormat": "read",
113 | "range": true,
114 | "refId": "A"
115 | },
116 | {
117 | "datasource": {
118 | "type": "prometheus",
119 | "uid": "$datasource"
120 | },
121 | "editorMode": "code",
122 | "expr": "irate(replica_num_write_ops{name=~\"$replica_name\"}[1m])",
123 | "format": "time_series",
124 | "hide": false,
125 | "instant": false,
126 | "interval": "",
127 | "legendFormat": "write",
128 | "range": true,
129 | "refId": "B"
130 | }
131 | ],
132 | "title": "IOPS",
133 | "type": "timeseries"
134 | },
135 | {
136 | "datasource": {
137 | "type": "prometheus",
138 | "uid": "$datasource"
139 | },
140 | "fieldConfig": {
141 | "defaults": {
142 | "color": {
143 | "mode": "palette-classic"
144 | },
145 | "custom": {
146 | "axisBorderShow": false,
147 | "axisCenteredZero": false,
148 | "axisColorMode": "text",
149 | "axisLabel": "",
150 | "axisPlacement": "auto",
151 | "barAlignment": 0,
152 | "drawStyle": "line",
153 | "fillOpacity": 10,
154 | "gradientMode": "none",
155 | "hideFrom": {
156 | "legend": false,
157 | "tooltip": false,
158 | "viz": false
159 | },
160 | "insertNulls": false,
161 | "lineInterpolation": "linear",
162 | "lineStyle": {
163 | "fill": "solid"
164 | },
165 | "lineWidth": 1,
166 | "pointSize": 5,
167 | "scaleDistribution": {
168 | "type": "linear"
169 | },
170 | "showPoints": "never",
171 | "spanNulls": false,
172 | "stacking": {
173 | "group": "A",
174 | "mode": "none"
175 | },
176 | "thresholdsStyle": {
177 | "mode": "off"
178 | }
179 | },
180 | "mappings": [ ],
181 | "thresholds": {
182 | "mode": "absolute",
183 | "steps": [
184 | {
185 | "color": "green",
186 | "value": null
187 | }
188 | ]
189 | },
190 | "unit": "binBps"
191 | },
192 | "overrides": [ ]
193 | },
194 | "gridPos": {
195 | "h": 8,
196 | "w": 12,
197 | "x": 12,
198 | "y": 0
199 | },
200 | "id": 2,
201 | "options": {
202 | "legend": {
203 | "calcs": [ ],
204 | "displayMode": "list",
205 | "placement": "bottom",
206 | "showLegend": true
207 | },
208 | "tooltip": {
209 | "mode": "multi",
210 | "sort": "none"
211 | }
212 | },
213 | "pluginVersion": "10.4.0",
214 | "targets": [
215 | {
216 | "datasource": {
217 | "uid": "$datasource"
218 | },
219 | "editorMode": "code",
220 | "exemplar": true,
221 | "expr": "irate(replica_bytes_read{name=~\"$replica_name\"}[1m])",
222 | "interval": "",
223 | "legendFormat": "read",
224 | "range": true,
225 | "refId": "A"
226 | },
227 | {
228 | "datasource": {
229 | "type": "prometheus",
230 | "uid": "$datasource"
231 | },
232 | "editorMode": "code",
233 | "expr": "irate(replica_bytes_written{name=~\"$replica_name\"}[1m])",
234 | "hide": false,
235 | "instant": false,
236 | "legendFormat": "write",
237 | "range": true,
238 | "refId": "B"
239 | }
240 | ],
241 | "title": "Throughput",
242 | "type": "timeseries"
243 | },
244 | {
245 | "datasource": {
246 | "type": "prometheus",
247 | "uid": "$datasource"
248 | },
249 | "fieldConfig": {
250 | "defaults": {
251 | "color": {
252 | "mode": "palette-classic"
253 | },
254 | "custom": {
255 | "axisBorderShow": false,
256 | "axisCenteredZero": false,
257 | "axisColorMode": "text",
258 | "axisLabel": "",
259 | "axisPlacement": "auto",
260 | "barAlignment": 0,
261 | "drawStyle": "line",
262 | "fillOpacity": 10,
263 | "gradientMode": "none",
264 | "hideFrom": {
265 | "legend": false,
266 | "tooltip": false,
267 | "viz": false
268 | },
269 | "insertNulls": false,
270 | "lineInterpolation": "linear",
271 | "lineStyle": {
272 | "fill": "solid"
273 | },
274 | "lineWidth": 1,
275 | "pointSize": 5,
276 | "scaleDistribution": {
277 | "type": "linear"
278 | },
279 | "showPoints": "never",
280 | "spanNulls": false,
281 | "stacking": {
282 | "group": "A",
283 | "mode": "none"
284 | },
285 | "thresholdsStyle": {
286 | "mode": "off"
287 | }
288 | },
289 | "mappings": [ ],
290 | "thresholds": {
291 | "mode": "absolute",
292 | "steps": [
293 | {
294 | "color": "green",
295 | "value": null
296 | }
297 | ]
298 | },
299 | "unit": "s"
300 | },
301 | "overrides": [ ]
302 | },
303 | "gridPos": {
304 | "h": 8,
305 | "w": 12,
306 | "x": 6,
307 | "y": 8
308 | },
309 | "id": 3,
310 | "options": {
311 | "legend": {
312 | "calcs": [ ],
313 | "displayMode": "list",
314 | "placement": "bottom",
315 | "showLegend": true
316 | },
317 | "tooltip": {
318 | "mode": "multi",
319 | "sort": "none"
320 | }
321 | },
322 | "pluginVersion": "10.4.0",
323 | "targets": [
324 | {
325 | "datasource": {
326 | "uid": "$datasource"
327 | },
328 | "editorMode": "code",
329 | "exemplar": true,
330 | "expr": "((irate(replica_read_latency_us{name=~\"$replica_name\"}[1m]))/(irate(replica_num_read_ops{name=~\"$replica_name\"}[1m])))/1000000",
331 | "interval": "",
332 | "legendFormat": "read",
333 | "range": true,
334 | "refId": "A"
335 | },
336 | {
337 | "datasource": {
338 | "type": "prometheus",
339 | "uid": "$datasource"
340 | },
341 | "editorMode": "code",
342 | "expr": "((irate(replica_write_latency_us{name=~\"$replica_name\"}[1m]))/(irate(replica_num_write_ops{name=~\"$replica_name\"}[1m])))/1000000",
343 | "hide": false,
344 | "instant": false,
345 | "legendFormat": "write",
346 | "range": true,
347 | "refId": "B"
348 | }
349 | ],
350 | "title": "Latency",
351 | "type": "timeseries"
352 | }
353 | ],
354 | "refresh": "5s",
355 | "schemaVersion": 39,
356 | "tags": [
357 | "OpenEBS",
358 | "Mayastor"
359 | ],
360 | "templating": {
361 | "list": [
362 | {
363 | "current": {
364 | "selected": false,
365 | "text": "Prometheus",
366 | "value": "prometheus"
367 | },
368 | "hide": 0,
369 | "includeAll": false,
370 | "multi": false,
371 | "name": "datasource",
372 | "options": [ ],
373 | "query": "prometheus",
374 | "refresh": 1,
375 | "regex": "",
376 | "skipUrlSync": false,
377 | "type": "datasource"
378 | },
379 | {
380 | "current": {
381 | "selected": true,
382 | "text": [
383 | "All"
384 | ],
385 | "value": [
386 | "$__all"
387 | ]
388 | },
389 | "datasource": {
390 | "type": "prometheus",
391 | "uid": "${datasource}"
392 | },
393 | "definition": "label_values(replica_num_read_ops,name)",
394 | "hide": 0,
395 | "includeAll": true,
396 | "multi": true,
397 | "name": "replica_name",
398 | "options": [ ],
399 | "query": {
400 | "qryType": 1,
401 | "query": "label_values(replica_num_read_ops,name)",
402 | "refId": "PrometheusVariableQueryEditor-VariableQuery"
403 | },
404 | "refresh": 2,
405 | "regex": "",
406 | "skipUrlSync": false,
407 | "sort": 0,
408 | "type": "query"
409 | }
410 | ]
411 | },
412 | "time": {
413 | "from": "now-1h",
414 | "to": "now"
415 | },
416 | "timepicker": { },
417 | "timezone": "browser",
418 | "title": "OpenEBS / Replicated PV / Mayastor / Volume Replica",
419 | "uid": "fdl05xto1hn28e",
420 | "version": 6,
421 | "weekStart": ""
422 | }
423 |
--------------------------------------------------------------------------------
/deploy/charts/dashboards/mayastor/mayastor-volume.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "grafana",
8 | "uid": "-- Grafana --"
9 | },
10 | "enable": true,
11 | "hide": true,
12 | "iconColor": "rgba(0, 211, 255, 1)",
13 | "name": "Annotations & Alerts",
14 | "type": "dashboard"
15 | }
16 | ]
17 | },
18 | "editable": true,
19 | "fiscalYearStartMonth": 0,
20 | "graphTooltip": 0,
21 | "id": 42,
22 | "links": [ ],
23 | "panels": [
24 | {
25 | "datasource": {
26 | "type": "prometheus",
27 | "uid": "$datasource"
28 | },
29 | "fieldConfig": {
30 | "defaults": {
31 | "color": {
32 | "mode": "palette-classic"
33 | },
34 | "custom": {
35 | "axisBorderShow": false,
36 | "axisCenteredZero": false,
37 | "axisColorMode": "text",
38 | "axisLabel": "",
39 | "axisPlacement": "auto",
40 | "barAlignment": 0,
41 | "drawStyle": "line",
42 | "fillOpacity": 10,
43 | "gradientMode": "none",
44 | "hideFrom": {
45 | "legend": false,
46 | "tooltip": false,
47 | "viz": false
48 | },
49 | "insertNulls": false,
50 | "lineInterpolation": "linear",
51 | "lineStyle": {
52 | "fill": "solid"
53 | },
54 | "lineWidth": 1,
55 | "pointSize": 5,
56 | "scaleDistribution": {
57 | "type": "linear"
58 | },
59 | "showPoints": "never",
60 | "spanNulls": false,
61 | "stacking": {
62 | "group": "A",
63 | "mode": "none"
64 | },
65 | "thresholdsStyle": {
66 | "mode": "off"
67 | }
68 | },
69 | "mappings": [ ],
70 | "thresholds": {
71 | "mode": "absolute",
72 | "steps": [
73 | {
74 | "color": "green",
75 | "value": null
76 | }
77 | ]
78 | },
79 | "unit": "iops"
80 | },
81 | "overrides": [ ]
82 | },
83 | "gridPos": {
84 | "h": 8,
85 | "w": 12,
86 | "x": 0,
87 | "y": 0
88 | },
89 | "id": 1,
90 | "options": {
91 | "legend": {
92 | "calcs": [ ],
93 | "displayMode": "list",
94 | "placement": "bottom",
95 | "showLegend": true
96 | },
97 | "tooltip": {
98 | "mode": "multi",
99 | "sort": "none"
100 | }
101 | },
102 | "pluginVersion": "10.4.0",
103 | "targets": [
104 | {
105 | "datasource": {
106 | "uid": "$datasource"
107 | },
108 | "editorMode": "code",
109 | "exemplar": false,
110 | "expr": "irate(volume_num_read_ops{pv_name=~\"$pv_name\"}[1m])",
111 | "interval": "",
112 | "legendFormat": "read",
113 | "range": true,
114 | "refId": "A"
115 | },
116 | {
117 | "datasource": {
118 | "type": "prometheus",
119 | "uid": "$datasource"
120 | },
121 | "editorMode": "code",
122 | "expr": "irate(volume_num_write_ops{pv_name=~\"$pv_name\"}[1m])",
123 | "format": "time_series",
124 | "hide": false,
125 | "instant": false,
126 | "interval": "",
127 | "legendFormat": "write",
128 | "range": true,
129 | "refId": "B"
130 | }
131 | ],
132 | "title": "IOPS",
133 | "type": "timeseries"
134 | },
135 | {
136 | "datasource": {
137 | "type": "prometheus",
138 | "uid": "$datasource"
139 | },
140 | "fieldConfig": {
141 | "defaults": {
142 | "color": {
143 | "mode": "palette-classic"
144 | },
145 | "custom": {
146 | "axisBorderShow": false,
147 | "axisCenteredZero": false,
148 | "axisColorMode": "text",
149 | "axisLabel": "",
150 | "axisPlacement": "auto",
151 | "barAlignment": 0,
152 | "drawStyle": "line",
153 | "fillOpacity": 10,
154 | "gradientMode": "none",
155 | "hideFrom": {
156 | "legend": false,
157 | "tooltip": false,
158 | "viz": false
159 | },
160 | "insertNulls": false,
161 | "lineInterpolation": "linear",
162 | "lineStyle": {
163 | "fill": "solid"
164 | },
165 | "lineWidth": 1,
166 | "pointSize": 5,
167 | "scaleDistribution": {
168 | "type": "linear"
169 | },
170 | "showPoints": "never",
171 | "spanNulls": false,
172 | "stacking": {
173 | "group": "A",
174 | "mode": "none"
175 | },
176 | "thresholdsStyle": {
177 | "mode": "off"
178 | }
179 | },
180 | "mappings": [ ],
181 | "thresholds": {
182 | "mode": "absolute",
183 | "steps": [
184 | {
185 | "color": "green",
186 | "value": null
187 | }
188 | ]
189 | },
190 | "unit": "binBps"
191 | },
192 | "overrides": [ ]
193 | },
194 | "gridPos": {
195 | "h": 8,
196 | "w": 12,
197 | "x": 12,
198 | "y": 0
199 | },
200 | "id": 2,
201 | "options": {
202 | "legend": {
203 | "calcs": [ ],
204 | "displayMode": "list",
205 | "placement": "bottom",
206 | "showLegend": true
207 | },
208 | "tooltip": {
209 | "mode": "multi",
210 | "sort": "none"
211 | }
212 | },
213 | "pluginVersion": "10.4.0",
214 | "targets": [
215 | {
216 | "datasource": {
217 | "uid": "$datasource"
218 | },
219 | "editorMode": "code",
220 | "exemplar": true,
221 | "expr": "irate(volume_bytes_read{pv_name=~\"$pv_name\"}[1m])",
222 | "interval": "",
223 | "legendFormat": "read",
224 | "range": true,
225 | "refId": "A"
226 | },
227 | {
228 | "datasource": {
229 | "type": "prometheus",
230 | "uid": "$datasource"
231 | },
232 | "editorMode": "code",
233 | "expr": "irate(volume_bytes_written{pv_name=~\"$pv_name\"}[1m])",
234 | "hide": false,
235 | "instant": false,
236 | "legendFormat": "write",
237 | "range": true,
238 | "refId": "B"
239 | }
240 | ],
241 | "title": "Throughput",
242 | "type": "timeseries"
243 | },
244 | {
245 | "datasource": {
246 | "type": "prometheus",
247 | "uid": "$datasource"
248 | },
249 | "fieldConfig": {
250 | "defaults": {
251 | "color": {
252 | "mode": "palette-classic"
253 | },
254 | "custom": {
255 | "axisBorderShow": false,
256 | "axisCenteredZero": false,
257 | "axisColorMode": "text",
258 | "axisLabel": "",
259 | "axisPlacement": "auto",
260 | "barAlignment": 0,
261 | "drawStyle": "line",
262 | "fillOpacity": 10,
263 | "gradientMode": "none",
264 | "hideFrom": {
265 | "legend": false,
266 | "tooltip": false,
267 | "viz": false
268 | },
269 | "insertNulls": false,
270 | "lineInterpolation": "linear",
271 | "lineStyle": {
272 | "fill": "solid"
273 | },
274 | "lineWidth": 1,
275 | "pointSize": 5,
276 | "scaleDistribution": {
277 | "type": "linear"
278 | },
279 | "showPoints": "never",
280 | "spanNulls": false,
281 | "stacking": {
282 | "group": "A",
283 | "mode": "none"
284 | },
285 | "thresholdsStyle": {
286 | "mode": "off"
287 | }
288 | },
289 | "mappings": [ ],
290 | "thresholds": {
291 | "mode": "absolute",
292 | "steps": [
293 | {
294 | "color": "green",
295 | "value": null
296 | }
297 | ]
298 | },
299 | "unit": "s"
300 | },
301 | "overrides": [ ]
302 | },
303 | "gridPos": {
304 | "h": 8,
305 | "w": 12,
306 | "x": 6,
307 | "y": 8
308 | },
309 | "id": 3,
310 | "options": {
311 | "legend": {
312 | "calcs": [ ],
313 | "displayMode": "list",
314 | "placement": "bottom",
315 | "showLegend": true
316 | },
317 | "tooltip": {
318 | "mode": "multi",
319 | "sort": "none"
320 | }
321 | },
322 | "pluginVersion": "10.4.0",
323 | "targets": [
324 | {
325 | "datasource": {
326 | "uid": "$datasource"
327 | },
328 | "editorMode": "code",
329 | "exemplar": true,
330 | "expr": "((irate(volume_read_latency_us{pv_name=~\"$pv_name\"}[1m]))/(irate(volume_num_read_ops{pv_name=~\"$pv_name\"}[1m])))/1000000",
331 | "interval": "",
332 | "legendFormat": "read",
333 | "range": true,
334 | "refId": "A"
335 | },
336 | {
337 | "datasource": {
338 | "type": "prometheus",
339 | "uid": "$datasource"
340 | },
341 | "editorMode": "code",
342 | "expr": "((irate(volume_write_latency_us{pv_name=~\"$pv_name\"}[1m]))/(irate(volume_num_write_ops{pv_name=~\"$pv_name\"}[1m])))/1000000",
343 | "hide": false,
344 | "instant": false,
345 | "legendFormat": "write",
346 | "range": true,
347 | "refId": "B"
348 | }
349 | ],
350 | "title": "Latency",
351 | "type": "timeseries"
352 | }
353 | ],
354 | "refresh": "5s",
355 | "schemaVersion": 39,
356 | "tags": [
357 | "OpenEBS",
358 | "Mayastor"
359 | ],
360 | "templating": {
361 | "list": [
362 | {
363 | "current": {
364 | "selected": false,
365 | "text": "Prometheus",
366 | "value": "prometheus"
367 | },
368 | "hide": 0,
369 | "includeAll": false,
370 | "multi": false,
371 | "name": "datasource",
372 | "options": [ ],
373 | "query": "prometheus",
374 | "refresh": 1,
375 | "regex": "",
376 | "skipUrlSync": false,
377 | "type": "datasource"
378 | },
379 | {
380 | "current": {
381 | "selected": true,
382 | "text": [
383 | "pvc-d070ac1c-6bb7-4ece-9893-5471c0c636a8"
384 | ],
385 | "value": [
386 | "pvc-d070ac1c-6bb7-4ece-9893-5471c0c636a8"
387 | ]
388 | },
389 | "datasource": {
390 | "type": "prometheus",
391 | "uid": "${datasource}"
392 | },
393 | "definition": "label_values(volume_num_read_ops,pv_name)",
394 | "hide": 0,
395 | "includeAll": true,
396 | "multi": true,
397 | "name": "pv_name",
398 | "options": [ ],
399 | "query": {
400 | "qryType": 1,
401 | "query": "label_values(volume_num_read_ops,pv_name)",
402 | "refId": "PrometheusVariableQueryEditor-VariableQuery"
403 | },
404 | "refresh": 2,
405 | "regex": "",
406 | "skipUrlSync": false,
407 | "sort": 0,
408 | "type": "query"
409 | }
410 | ]
411 | },
412 | "time": {
413 | "from": "now-1h",
414 | "to": "now"
415 | },
416 | "timepicker": { },
417 | "timezone": "browser",
418 | "title": "OpenEBS / Replicated PV / Mayastor / Volume",
419 | "uid": "fdl05gxyisqo0d",
420 | "version": 6,
421 | "weekStart": ""
422 | }
423 |
--------------------------------------------------------------------------------
/deploy/charts/rules/lvmLocalPV/lvmlocalpv-rules.json:
--------------------------------------------------------------------------------
1 | {
2 | "groups": [
3 | {
4 | "name": "lvm-pool",
5 | "rules": [
6 | {
7 | "alert": "LVMVolumeGroupMissingPhysicalVolume",
8 | "annotations": {
9 | "componentType": "volume group",
10 | "description": "LVM volume group '{{ $labels.name }}' on node '{{ $labels.instance }}' is missing {{ $value }} underlying physical volume(s).",
11 | "summary": "LVM volume group '{{ $labels.name }}' is missing the underlying physical volume.",
12 | "vgName": "{{ $labels.name }}"
13 | },
14 | "expr": "lvm_vg_missing_pv_count > 0",
15 | "for": "5m",
16 | "labels": {
17 | "engine": "localpv-lvm",
18 | "product": "openebs",
19 | "severity": "critical"
20 | }
21 | },
22 | {
23 | "alert": "LVMVolumeGroupCapacityLow",
24 | "annotations": {
25 | "componentType": "volume group",
26 | "description": "LVM volume group '{{ $labels.name }}' on node '{{ $labels.instance }}' has {{ with printf \"lvm_vg_free_size_bytes{instance='%s',name='%s'}\" $labels.instance $labels.name | query }} {{ . | first | value }} {{ end }}bytes of space remaining",
27 | "summary": "LVM volume group '{{ $labels.name }}' is running low on capacity. Already {{ $value }}% of total capacity is consumed.",
28 | "vgName": "{{ $labels.name }}"
29 | },
30 | "expr": "((lvm_vg_total_size_bytes - lvm_vg_free_size_bytes)/lvm_vg_total_size_bytes)*100 > 90",
31 | "for": "5m",
32 | "labels": {
33 | "engine": "localpv-lvm",
34 | "product": "openebs",
35 | "severity": "critical"
36 | }
37 | },
38 | {
39 | "alert": "LVMThinPoolCapacityLow",
40 | "annotations": {
41 | "componentType": "logical volume",
42 | "description": "LVM thin pool '{{ $labels.name }}' on node '{{ $labels.instance }}' has {{ with printf \"lvm_lv_total_size_bytes{instance='%s',name='%s',segtype='%s'}-((lvm_lv_used_percent{instance='%s',name='%s',segtype='%s'}*lvm_lv_total_size_bytes{instance='%s',name='%s',segtype='%s'})/100)\" $labels.instance $labels.name $labels.segtype $labels.instance $labels.name $labels.segtype $labels.instance $labels.name $labels.segtype | query }} {{ . | first | value }} {{ end }}bytes of space remaining",
43 | "lvName": "{{ $labels.name }}",
44 | "summary": "LVM thin pool '{{ $labels.name }}' is running low on capacity. Already {{ $value }}% of total capacity is consumed."
45 | },
46 | "expr": "lvm_lv_used_percent{segtype=\"thin-pool\"} > 90",
47 | "for": "5m",
48 | "labels": {
49 | "engine": "localpv-lvm",
50 | "product": "openebs",
51 | "severity": "critical"
52 | }
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/deploy/charts/rules/npd/npd-rules.json:
--------------------------------------------------------------------------------
1 | {
2 | "groups": [
3 | {
4 | "name": "volume-node",
5 | "rules": [
6 | {
7 | "alert": "VolumeNodeFileSystemIsReadOnly",
8 | "annotations": {
9 | "description": "Persistent Volume's filesystem on node '{{ $labels.node }}' for persistent volume claim '{{ $labels.persistentvolumeclaim }}' has become read-only",
10 | "summary": "Volume mount failed for persistent volume claim '{{ $labels.persistentvolumeclaim }}' on node '{{ $labels.node }}' due to read-only file-system"
11 | },
12 | "expr": "kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason=\"FilesystemIsReadOnly\"} > 0",
13 | "for": "5m",
14 | "labels": {
15 | "severity": "critical"
16 | }
17 | },
18 | {
19 | "alert": "VolumeNodeExt4Error",
20 | "annotations": {
21 | "description": "Persistent Volume's on node '{{ $labels.node }}' persistent volume claim '{{ $labels.persistentvolumeclaim }}' encountering ext4 filesystem error",
22 | "summary": "Node '{{ $labels.node }}' has encountered errors on ext4 file-system on volume having claim '{{ $labels.persistentvolumeclaim }}'"
23 | },
24 | "expr": "kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason=\"Ext4Error\"} > 0",
25 | "for": "5m",
26 | "labels": {
27 | "severity": "critical"
28 | }
29 | },
30 | {
31 | "alert": "VolumeNodeIOError",
32 | "annotations": {
33 | "description": "Persistent Volume on node '{{ $labels.node }}' for persistent volume claim '{{ $labels.persistentvolumeclaim }}' encountering errors w.r.t buffer I/O ",
34 | "summary": "IO errors encountered on volume having persistent volume claim '{{ $labels.persistentvolumeclaim }}' on node '{{ $labels.node }}'"
35 | },
36 | "expr": "kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason=\"IOError\"} > 0",
37 | "for": "5m",
38 | "labels": {
39 | "severity": "critical"
40 | }
41 | },
42 | {
43 | "alert": "VolumeNodeExt4Warning",
44 | "annotations": {
45 | "description": "Persistent Volume on node '{{ $labels.node }}' receiving ext4 filesystem warning for persistent volume claim '{{ $labels.persistentvolumeclaim }}'",
46 | "summary": "Node '{{ $labels.node }}' has encountered warning on ext4 file-system on volume having claim '{{ $labels.persistentvolumeclaim }}'"
47 | },
48 | "expr": "kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason=\"Ext4Warning\"} > 0",
49 | "for": "5m",
50 | "labels": {
51 | "severity": "critical"
52 | }
53 | }
54 | ]
55 | }
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/deploy/charts/rules/volume/volume-rules.json:
--------------------------------------------------------------------------------
1 | {
2 | "groups": [
3 | {
4 | "name": "persistent-volume-claim",
5 | "rules": [
6 | {
7 | "alert": "StalePersistentVolumeClaim",
8 | "annotations": {
9 | "description": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has no consumer",
10 | "summary": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' in namespace '{{ $labels.namespace }}' is not consumed by any pod in any namespace"
11 | },
12 | "expr": "kube_persistentvolumeclaim_info unless (kube_persistentvolumeclaim_info * on(persistentvolumeclaim) group_left (max by (persistentvolumeclaim) (kube_pod_spec_volumes_persistentvolumeclaims_info)))) == 1",
13 | "for": "5m",
14 | "labels": {
15 | "severity": "info"
16 | }
17 | },
18 | {
19 | "alert": "PendingPersistentVolumeClaim",
20 | "annotations": {
21 | "description": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has been in pending state for more than 5 minutes",
22 | "summary": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' pending in namespace '{{ $labels.namespace }}'"
23 | },
24 | "expr": "kube_persistentvolumeclaim_status_phase{phase=\"Pending\"} == 1",
25 | "for": "5m",
26 | "labels": {
27 | "severity": "warning"
28 | }
29 | },
30 | {
31 | "alert": "LostPersistentVolumeClaim",
32 | "annotations": {
33 | "description": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has been in lost state for more than 5 minutes",
34 | "summary": "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' in namespace '{{ $labels.namespace }}' lost it's corresponding persistent volume"
35 | },
36 | "expr": "kube_persistentvolumeclaim_status_phase{phase=\"Lost\"} == 1",
37 | "for": "5m",
38 | "labels": {
39 | "severity": "warning"
40 | }
41 | }
42 | ]
43 | }
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/deploy/charts/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | OpenEBS monitoring has been installed.
2 | Check its status by running:
3 | $ kubectl get pods -n {{ .Release.Namespace }} -o wide
4 |
5 | Use `kubectl get svc -n {{ .Release.Namespace }}` to list all the
6 | services in the `{{ .Release.Namespace }}` namespace.
7 |
8 | To access the dashboards, form the Grafana URL and open it in the browser
9 | {{- if (index $.Values "kube-prometheus-stack" "install") }}
10 | {{- if (index $.Values "kube-prometheus-stack" "grafana" "ingress" "enabled") }}
11 | {{- range $host := (index $.Values "kube-prometheus-stack" "grafana" "ingress" "hosts") }}
12 | http{{ if (index $.Values "kube-prometheus-stack" "grafana" "ingress" "tls") }}s{{ end }}://{{ $host }}{{ regexReplaceAll "\\(.*\\)" (index $.Values "kube-prometheus-stack" "grafana" "ingress" "path") "" }}
13 | {{- end }}
14 | {{- else if contains "NodePort" (index $.Values "kube-prometheus-stack" "grafana" "service" "type") }}
15 | export NODE_PORT={{ index $.Values "kube-prometheus-stack" "grafana" "service" "nodePort" }}
16 | export NODE_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "call-nested" (list . "kube-prometheus-stack.grafana" "grafana.name") }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].spec.nodeName}")
17 | export NODE_IP=$(kubectl get node $NODE_NAME -o jsonpath='{$.status.addresses[?(@.type=="ExternalIP")].address}')
18 | echo http://$NODE_IP:$NODE_PORT
19 | NOTE: The above IP should be a public IP
20 | echo
21 | Or you could use a port-forward to forward to 8080
22 | export SVC_NAME=$(kubectl -n {{ .Release.Namespace }} get svc -l "app.kubernetes.io/name={{ include "call-nested" (list . "kube-prometheus-stack.grafana" "grafana.name") }},app.kubernetes.io/instance={{ .Release.Name }}" -o name)
23 | kubectl --namespace {{ .Release.Namespace }} port-forward $SVC_NAME 8080:80
24 | echo "Visit http://127.0.0.1:8080"
25 |
26 | {{- else if contains "ClusterIP" (index $.Values "kube-prometheus-stack" "grafana" "service" "type") }}
27 | export PORT= {{ index $.Values "kube-prometheus-stack" "grafana" "service" "port" }}
28 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "call-nested" (list . "kube-prometheus-stack.grafana" "grafana.name") }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
29 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 32515:$PORT
30 | echo "Visit http://127.0.0.1:32515"
31 | {{- end }}
32 | {{- end }}
33 |
34 | For more information, visit our Slack at https://openebs.io/community
35 |
--------------------------------------------------------------------------------
/deploy/charts/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/* vim: set filetype=mustache: */}}
2 | {{/*
3 | Expand the name of the chart.
4 | */}}
5 | {{- define "monitoring.name" -}}
6 | {{- default .Chart.Name .Values.nameOverride | trunc 50 | trimSuffix "-" }}
7 | {{- end }}
8 |
9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | If release name contains chart name it will be used as a full name.
13 | */}}
14 | {{- define "monitoring.fullname" -}}
15 | {{- if .Values.fullnameOverride }}
16 | {{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" }}
17 | {{- else }}
18 | {{- $name := default .Chart.Name .Values.nameOverride }}
19 | {{- if contains $name .Release.Name }}
20 | {{- .Release.Name | trunc 26 | trimSuffix "-" }}
21 | {{- else }}
22 | {{- printf "%s-%s" .Release.Name $name | trunc 26 | trimSuffix "-" }}
23 | {{- end }}
24 | {{- end }}
25 | {{- end }}
26 |
27 | {{/*
28 | Allow the release namespace to be overridden for multi-namespace deployments in combined charts
29 | */}}
30 | {{- define "monitoring.namespace" -}}
31 | {{- if .Values.namespaceOverride -}}
32 | {{- .Values.namespaceOverride -}}
33 | {{- else -}}
34 | {{- .Release.Namespace -}}
35 | {{- end -}}
36 | {{- end -}}
37 |
38 |
39 | {{/*
40 | Create chart name and version as used by the chart label.
41 | */}}
42 | {{- define "monitoring.chart" -}}
43 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
44 | {{- end }}
45 |
46 | {{/*
47 | Common labels
48 | */}}
49 | {{- define "monitoring.labels" -}}
50 | helm.sh/chart: {{ include "monitoring.chart" . }}
51 | {{ include "monitoring.selectorLabels" . }}
52 | {{- if .Chart.AppVersion }}
53 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
54 | {{- end }}
55 | app.kubernetes.io/managed-by: {{ .Release.Service }}
56 | {{- end }}
57 |
58 | {{/*
59 | Selector labels
60 | */}}
61 | {{- define "monitoring.selectorLabels" -}}
62 | app.kubernetes.io/name: {{ include "monitoring.name" . }}
63 | app.kubernetes.io/instance: {{ .Release.Name }}
64 | release: {{ $.Release.Name | quote }}
65 | {{- end }}
66 |
67 | {{/*
68 | Template to support multiple levels of sub-charts
69 |
70 | Call a template from the context of a subchart.
71 |
72 | Usage:
73 | {{ include "call-nested" (list . "" "") }}
74 | */}}
75 | {{- define "call-nested" }}
76 | {{- $dot := index . 0 }}
77 | {{- $subchart := index . 1 | splitList "." }}
78 | {{- $template := index . 2 }}
79 | {{- $values := $dot.Values }}
80 | {{- range $subchart }}
81 | {{- $values = index $values . }}
82 | {{- end }}
83 | {{- if $values.enabled }}
84 | {{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }}
85 | {{- end }}
86 | {{- end }}
87 |
88 |
--------------------------------------------------------------------------------
/deploy/charts/templates/dashboards-json-configmap.yaml:
--------------------------------------------------------------------------------
1 | {{- $grafanaSidecarDashboardsLabel := index .Values "kube-prometheus-stack" "grafana" "sidecar" "dashboards" "label" }}
2 | {{- $dashboards := dict -}}
3 | {{- range $monitoringAddon,$fields := .Values.openebsMonitoringAddon }}
4 | {{- if (and (hasKey $fields "enabled") ($fields.enabled)) }}
5 | {{- if (hasKey $fields "dashboards") }}
6 | {{- if ($fields.dashboards.enabled) }}
7 | {{ $_ := set $dashboards $monitoringAddon $fields.dashboards.enabled }}
8 | {{- end }}
9 | {{- end }}
10 | {{- end }}
11 | {{- end }}
12 | {{- $files := .Files.Glob "dashboards/**.json" }}
13 | {{- if $files }}
14 | {{- range $fileName, $fileContents := $files }}
15 | {{- $dirName := split "/" $fileName }}
16 | {{- if and (hasKey $dashboards $dirName._1 ) $dashboards }}
17 | {{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $fileName "${2}" }}
18 | apiVersion: v1
19 | kind: ConfigMap
20 | metadata:
21 | name: {{ lower (printf "%s-%s" (include "monitoring.fullname" $) $dashboardName) | trunc 63 | trimSuffix "-" }}
22 | namespace: {{ template "monitoring.namespace" $ }}
23 | labels:
24 | {{ $grafanaSidecarDashboardsLabel }}: "1"
25 | app: {{ template "monitoring.name" $ }}-grafana
26 | {{ include "monitoring.labels" $ | indent 4 }}
27 | data:
28 | {{ $dashboardName }}.json: {{ $.Files.Get $fileName | toPrettyJson }}
29 | ---
30 | {{- end }}
31 | {{- end }}
32 | {{- end }}
33 |
--------------------------------------------------------------------------------
/deploy/charts/templates/podmonitors.yaml:
--------------------------------------------------------------------------------
1 | {{ if (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }}
2 | {{- range $monitoringAddon, $fields := .Values.openebsMonitoringAddon }}
3 | {{- if (and (hasKey $fields "enabled") ($fields.enabled)) }}
4 | {{- if (hasKey $fields "podMonitor") }}
5 | {{- if ($fields.podMonitor.enabled) }}
6 | apiVersion: monitoring.coreos.com/v1
7 | kind: PodMonitor
8 | metadata:
9 | name: {{ lower (printf "%s-%s" (include "monitoring.fullname" $) $monitoringAddon) | trunc 63 | trimSuffix "-" }}
10 | namespace: {{ template "monitoring.namespace" $ }}
11 | labels:
12 | app: {{ template "monitoring.name" $ }}-{{ $monitoringAddon }}
13 | {{ include "monitoring.labels" $ | indent 4 }}
14 | spec:
15 | selector:
16 | {{ toYaml $fields.podMonitor.selector | indent 4 }}
17 | namespaceSelector:
18 | {{ toYaml $fields.podMonitor.namespaceSelector | indent 4 }}
19 | podMetricsEndpoints:
20 | - targetPort: {{ $fields.podMonitor.podMetricsEndpoints.targetPort }}
21 | path: {{ $fields.podMonitor.podMetricsEndpoints.path }}
22 | {{- if $fields.podMonitor.podMetricsEndpoints.relabelings }}
23 | relabelings:
24 | {{ toYaml $fields.podMonitor.podMetricsEndpoints.relabelings | indent 8 }}
25 | {{- end }}
26 | ---
27 | {{- end }}
28 | {{- end }}
29 | {{- end }}
30 | {{- end }}
31 | {{- end }}
32 |
--------------------------------------------------------------------------------
/deploy/charts/templates/prometheusRules.yaml:
--------------------------------------------------------------------------------
1 | {{ if (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }}
2 | {{- $alertRules := dict -}}
3 | {{- range $monitoringAddon,$fields := .Values.openebsMonitoringAddon }}
4 | {{- if (and (hasKey $fields "enabled") ($fields.enabled)) }}
5 | {{- if (hasKey $fields "alertRules") }}
6 | {{- if ($fields.alertRules.enabled) }}
7 | {{ $_ := set $alertRules $monitoringAddon $fields.alertRules.enabled }}
8 | {{- end }}
9 | {{- end }}
10 | {{- end }}
11 | {{- end }}
12 | {{- $files := .Files.Glob "rules/**.json" }}
13 | {{- if $files }}
14 | {{- range $fileName, $fileContents := $files }}
15 | {{- $dirName := split "/" $fileName }}
16 | {{- if and (hasKey $alertRules $dirName._1 ) $alertRules }}
17 | {{- $ruleName := regexReplaceAll "(^.*/)(.*)\\.json$" $fileName "${2}" }}
18 | apiVersion: monitoring.coreos.com/v1
19 | kind: PrometheusRule
20 | metadata:
21 | name: {{ lower (printf "%s-%s" (include "monitoring.name" $) $ruleName) | trunc 63 | trimSuffix "-" }}
22 | namespace: {{ template "monitoring.namespace" $ }}
23 | labels:
24 | app: {{ template "monitoring.name" $ }}
25 | {{ include "monitoring.labels" $ | indent 4 }}
26 | spec:
27 | {{ $.Files.Get $fileName | indent 2 }}
28 | ---
29 | {{- end }}
30 | {{- end }}
31 | {{- end }}
32 | {{- end }}
33 |
--------------------------------------------------------------------------------
/deploy/charts/templates/servicemonitors.yaml:
--------------------------------------------------------------------------------
1 | {{ if (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }}
2 | {{- range $monitoringAddon, $fields := .Values.openebsMonitoringAddon }}
3 | {{- if (and (hasKey $fields "enabled") ($fields.enabled)) }}
4 | {{- if (hasKey $fields "serviceMonitor") }}
5 | {{- if ($fields.serviceMonitor.enabled) }}
6 | apiVersion: monitoring.coreos.com/v1
7 | kind: ServiceMonitor
8 | metadata:
9 | name: {{ lower (printf "%s-%s" (include "monitoring.fullname" $) $monitoringAddon) | trunc 63 | trimSuffix "-" }}
10 | namespace: {{ template "monitoring.namespace" $ }}
11 | labels:
12 | app: {{ template "monitoring.name" $ }}-{{ $monitoringAddon }}
13 | {{ include "monitoring.labels" $ | indent 4 }}
14 | spec:
15 | selector:
16 | {{ toYaml $fields.serviceMonitor.selector | indent 4 }}
17 | namespaceSelector:
18 | {{ toYaml $fields.serviceMonitor.namespaceSelector | indent 4 }}
19 | endpoints:
20 | - port: {{ $fields.serviceMonitor.endpoints.port }}
21 | path: {{ $fields.serviceMonitor.endpoints.path }}
22 | {{- if $fields.serviceMonitor.endpoints.relabelings }}
23 | relabelings:
24 | {{ toYaml $fields.serviceMonitor.endpoints.relabelings | indent 8 }}
25 | {{- end }}
26 | ---
27 | {{- end }}
28 | {{- end }}
29 | {{- end }}
30 | {{- end }}
31 | {{- end }}
32 |
--------------------------------------------------------------------------------
/deploy/charts/values.yaml:
--------------------------------------------------------------------------------
1 | # Default values for monitoring.
2 | # This is a YAML-formatted file.
3 | # Declare variables to be passed into your templates.
4 |
5 | ## Provide a name in place of monitoring for `app:` labels
6 | ##
7 | nameOverride: ""
8 |
9 | ## Override the deployment namespace
10 | ##
11 | namespaceOverride: ""
12 |
13 | ## Provide a name to substitute for the full names of resources
14 | ##
15 | fullnameOverride: ""
16 |
17 | ## Configuration for kube-prometheus-stack subchart
18 | kube-prometheus-stack:
19 | install: true
20 |
21 | global:
22 | rbac:
23 | pspEnabled: false
24 |
25 | kube-state-metrics:
26 | podSecurityPolicy:
27 | enabled: false
28 |
29 | prometheus-node-exporter:
30 | rbac:
31 | pspEnabled: false
32 |
33 | ## privilege and access control settings for node-exporter
34 | securityContext:
35 | fsGroup: 65534
36 | runAsGroup: 0
37 | runAsNonRoot: false
38 | runAsUser: 0
39 |
40 | ## Additional container arguments
41 | extraArgs:
42 | - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+)($|/)
43 | - --collector.filesystem.fs-types-exclude=^(tmpfs|autofs|binfmt_misc|cgroup|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|sysfs|tracefs)$
44 | - --collector.diskstats.device-exclude=^(ram|loop|fd|sr|(h|s|v|xv)d[a-z]+|nvme\d+n\d+p|nvme\d+c\d+n)\d+$
45 |
46 | prometheus:
47 | service:
48 | type: NodePort
49 | nodePort: 32514
50 |
51 | prometheusSpec:
52 | ## If true, a nil or {} value for prometheus.prometheusSpec.serviceMonitorSelector will cause the
53 | ## prometheus resource to be created with selectors based on values in the helm deployment,
54 | ## which will also match the servicemonitors created
55 | ##
56 | serviceMonitorSelectorNilUsesHelmValues: false
57 |
58 | ## If true, a nil or {} value for prometheus.prometheusSpec.podMonitorSelector will cause the
59 | ## prometheus resource to be created with selectors based on values in the helm deployment,
60 | ## which will also match the podmonitors created
61 | ##
62 | podMonitorSelectorNilUsesHelmValues: false
63 |
64 | ## If true, a nil or {} value for prometheus.prometheusSpec.ruleSelector will cause the
65 | ## prometheus resource to be created with selectors based on values in the helm deployment,
66 | ## which will also match the PrometheusRule resources created
67 | ##
68 | ruleSelectorNilUsesHelmValues: false
69 |
70 | ## Number of replicas of each shard to deploy for a Prometheus deployment.
71 | ## Number of replicas multiplied by shards is the total number of Pods created.
72 | ##
73 | replicas: 1
74 |
75 | ## Prometheus StorageSpec for persistent data
76 | ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md
77 | ##
78 | storageSpec:
79 | volumeClaimTemplate:
80 | metadata:
81 | name: openebs-prometheus-pv
82 | spec:
83 | # This storageClass is backed by openebs localpv-provisioner.
84 | storageClassName: openebs-hostpath
85 | accessModes: ["ReadWriteOnce"]
86 | resources:
87 | requests:
88 | storage: 1Gi
89 |
90 | alertmanager:
91 | ## Deploy alertmanager
92 | ##
93 | enabled: true
94 |
95 | config:
96 | global:
97 | resolve_timeout: 5m
98 | route:
99 | group_by: ["alertname", "job", "volName"]
100 | group_wait: 30s
101 | group_interval: 5m
102 | repeat_interval: 4h
103 | receiver: "null"
104 | ## This route specifically groups openebs alerts.
105 | routes:
106 | - matchers:
107 | - product="openebs"
108 | receiver: "null"
109 | ## Add receivers as required. Ref: https://prometheus.io/docs/alerting/latest/configuration/#receiver-integration-settings
110 | receivers:
111 | - name: "null"
112 | templates:
113 | - /etc/alertmanager/config/*.tmpl
114 |
115 | service:
116 | type: NodePort
117 | nodePort: 30903
118 |
119 | alertmanagerSpec:
120 | ## Size is the expected size of the alertmanager cluster. The controller will eventually make the size of the
121 | ## running cluster equal to the expected size.
122 | replicas: 1
123 |
124 | ## Storage is the definition of how storage will be used by the Alertmanager instances.
125 | ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md
126 | ##
127 | storage:
128 | {}
129 | # volumeClaimTemplate:
130 | # metadata:
131 | # name: alert-pv
132 | # spec:
133 | # # This storageClass is backed by openebs localpv-provisioner.
134 | # storageClassName: openebs-hostpath
135 | # accessModes: ["ReadWriteOnce"]
136 | # resources:
137 | # requests:
138 | # storage: 1Gi
139 | # selector: {}
140 |
141 | prometheusOperator:
142 | enabled: true
143 |
144 | ## Prometheus-Operator v0.39.0 and later support TLS natively.
145 | ##
146 | # tls:
147 | # enabled: false
148 |
149 | grafana:
150 | enabled: true
151 |
152 | rbac:
153 | pspEnabled: false
154 |
155 | ## In order to render HTML and Javascript in a text panel without being sanitized
156 | ## enable the `disable_sanitize_html` settings in Grafana ini file
157 | grafana.ini:
158 | panels:
159 | disable_sanitize_html: true
160 |
161 | service:
162 | type: NodePort
163 | nodePort: 32515
164 |
165 | ## Deploy default dashboards.
166 | ##
167 | defaultDashboardsEnabled: true
168 | adminPassword: admin
169 |
170 | sidecar:
171 | dashboards:
172 | enabled: true
173 | # ConfigMaps with label below will be added to Grafana as dashboards.
174 | label: grafana_dashboard
175 |
176 | ## Pass the plugins you want installed as a list.
177 | ##
178 | plugins:
179 | - grafana-polystat-panel
180 | - snuids-trafficlights-panel
181 |
182 | ## Add persistent storage for Grafana
183 | persistence:
184 | enabled: true
185 | # This storageClass is backed by openebs localpv-provisioner.
186 | storageClassName: openebs-hostpath
187 | accessModes:
188 | - ReadWriteOnce
189 | size: 1Gi
190 |
191 | localpv-provisioner:
192 | enabled: true
193 | hostpathClass:
194 | name: openebs-hostpath
195 | # -- Enable default hostpath localpv StorageClass.
196 | enabled: true
197 | analytics:
198 | enabled: true
199 |
200 | ## Configuration for node-problem-detector subchart
201 | node-problem-detector:
202 | install: false
203 |
204 | ## Volume for storing logs
205 | extraVolumes:
206 | - name: kmsg
207 | hostPath:
208 | path: /dev/kmsg
209 |
210 | extraVolumeMounts:
211 | - name: kmsg
212 | mountPath: /dev/kmsg
213 | readOnly: true
214 |
215 | ## Enabling service monitors of npd
216 | metrics:
217 | serviceMonitor:
218 | enabled: true
219 |
220 | ## Configuration for installing monitoring addons
221 | openebsMonitoringAddon:
222 | lvmLocalPV:
223 | enabled: true
224 | dashboards:
225 | enabled: true
226 | alertRules:
227 | enabled: true
228 | serviceMonitor:
229 | enabled: true
230 |
231 | ## Endpoints of the selected service to be monitored
232 | endpoints:
233 | ## Name of the endpoint's service port
234 | ## Mutually exclusive with targetPort
235 | # port: ""
236 | port: metrics
237 |
238 | ## HTTP path to scrape for metrics
239 | # path: /metrics
240 | path: /metrics
241 |
242 | ## Label selector for services to which this ServiceMonitor applies
243 | # selector: {}
244 | # matchLabels: {}
245 |
246 | ## Example
247 |
248 | # selector:
249 | # matchLabels:
250 | # name: openebs-lvm-node
251 |
252 | selector:
253 | matchLabels:
254 | name: openebs-lvm-node
255 |
256 | ## Namespaces from which services are selected
257 | # namespaceSelector: []
258 | ## Match any namespace
259 | # any: true
260 |
261 | ## Example
262 |
263 | # namespaceSelector:
264 | # any: true
265 |
266 | ## Explicit list of namespace names to select
267 | # matchNames: []
268 |
269 | ## Example
270 |
271 | # namespaceSelector:
272 | # matchNames:
273 | # - openebs
274 | # - default
275 |
276 | namespaceSelector:
277 | any: true
278 |
279 | npd:
280 | enabled: false
281 | dashboards:
282 | enabled: false
283 | alertRules:
284 | enabled: false
285 |
286 | volume:
287 | enabled: true
288 | alertRules:
289 | enabled: true
290 |
291 | zfsLocalPV:
292 | enabled: true
293 | dashboards:
294 | enabled: true
295 |
296 | mayastor:
297 | enabled: true
298 | dashboards:
299 | enabled: true
300 | serviceMonitor:
301 | enabled: true
302 |
303 | ## Endpoints of the selected service to be monitored
304 | endpoints:
305 | ## Name of the endpoint's service port
306 | ## Mutually exclusive with targetPort
307 | # port: ""
308 | port: metrics
309 |
310 | ## HTTP path to scrape for metrics
311 | # path: /metrics
312 | path: /metrics
313 |
314 | selector:
315 | matchLabels:
316 | app: metrics-exporter-io-engine
317 |
318 | namespaceSelector:
319 | any: true
320 |
--------------------------------------------------------------------------------
/docs/extends-stack-with-umbrella-chart.md:
--------------------------------------------------------------------------------
1 | # Extending the monitoring stack
2 |
3 | ### Prerequisite
4 |
5 | - Helm 3+ installed
6 | - OpenEBS installed
7 |
8 | # What is a umbrella chart and why use it ?
9 |
10 | An umbrella chart is a way of encapsulate multiple complex charts with one chart.
11 |
12 | >Many of the charts in the CNCF Artifact Hub are "building blocks" for creating more advanced applications. But charts may be used to create instances of large-scale applications. In such cases, a single umbrella chart may have multiple subcharts, each of which functions as a piece of the whole.
13 |
14 | >The current best practice for composing a complex application from discrete parts is to create a top-level umbrella chart that exposes the global configurations, and then use the charts/ subdirectory to embed each of the components.
15 | Source: https://helm.sh/docs/howto/charts_tips_and_tricks/#complex-charts-with-many-dependencies
16 |
17 | Using an umbrella chart will allow you customize OpenEBS monitoring stack settings without modifying that chart content. It's also easier to update a dependency.
18 |
19 | To create your our umbrella chart, you will have a create a folder structure like this.
20 |
21 | ```
22 | 📦umbrella
23 | ┣ 📜Chart.yaml
24 | ┗ 📜values.yaml
25 | ```
26 |
27 | | File | Description |
28 | | ------ | ------ |
29 | | Chart.yaml | Contains your chart identification with a dependency to OpenEBS monitoring stack |
30 | | values.yaml | Contains all your settings values |
31 |
32 | # Umbrella chart with ingress and storage enabled
33 |
34 | Here a example that will enable ingress and storage for OpenEBS monitoring stack.
35 |
36 | In the file **Chart.yaml**, you will enter your umbrella chart information with a dependency to OpenEBS monitoring stack. The property name : `condition` is optional. That property will allow you to install that dependency or not depending of the value in `values.yaml`.
37 |
38 | #### Chart.yaml
39 | ````yaml
40 | apiVersion: v2
41 | name: monitoring-stack
42 | description: Umbrella Chart for OpenEBS monitoring stack
43 | icon: https://avatars.githubusercontent.com/u/20769039?s=200&v=4
44 | type: application
45 | version: 0.1.1
46 | appVersion: 1.0.0
47 | dependencies:
48 | - name: monitoring
49 | version: 0.4.8
50 | repository: "https://openebs.github.io/monitoring/"
51 | condition: monitoring.install
52 | ````
53 |
54 | In the file **values.yaml**, you will define your configuration for the monitoring stack.
55 |
56 | If you defined a **dependency condition** in **Chart.yaml**, you will have to define the value in that condition. In this example, the condition name is `monitoring.install`.
57 |
58 | if you provide only the condition value, you will deploy OpenEBS monitoring stack with the default values provided in there chart.
59 |
60 | #### value.yaml (with default values)
61 | ````yaml
62 | monitoring:
63 | install: true
64 | ````
65 |
66 | #### value.yaml (with ingress and storage)
67 |
68 | To use storage for the monitoring stack, you will have to create the storage class before using it. In the following example, I use a storage class named: `sc-metrics` which already exists in my cluster.
69 |
70 | Similarly you can also customize other parameters. For instance, if domain name has to be used to access the user interfaces, the `ingress` section needs to be updated. In the following example I use the value: `dev.dynamic.cluster109.local`.
71 |
72 | The applications will be accessible from :
73 | - http://dev.dynamic.cluster109.local/prometheus
74 | - http://dev.dynamic.cluster109.local/grafana
75 | - http://dev.dynamic.cluster109.local/alertmanager
76 |
77 | Here the content of **values.yaml** with those settings.
78 |
79 | ````yaml
80 | monitoring:
81 | install: true
82 |
83 | ## Configuration for kube-prometheus-stack subchart
84 | kube-prometheus-stack:
85 | # PROMETHEUS SECTION
86 | prometheus:
87 | ingress:
88 | enabled: true
89 | annotations:
90 | nginx.ingress.kubernetes.io/ssl-redirect: "false"
91 | paths:
92 | - /prometheus(/|$)(.*)
93 | hosts:
94 | - dev.dynamic.cluster109.local
95 |
96 | prometheusSpec:
97 | ## Prefix used to register routes, overriding externalUrl route.
98 | ## Useful for proxies that rewrite URLs.
99 | ##
100 | routePrefix: /prometheus
101 |
102 | ## Prometheus StorageSpec for persistent data
103 | ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md
104 | ##
105 | storageSpec:
106 | volumeClaimTemplate:
107 | metadata:
108 | name: prom
109 | spec:
110 | storageClassName: sc-metrics
111 | accessModes: [ "ReadWriteOnce" ]
112 | resources:
113 | requests:
114 | storage: 8Gi
115 |
116 | # ALERTMANAGER SECTION
117 | alertmanager:
118 | ingress:
119 | enabled: true
120 |
121 | annotations:
122 | nginx.ingress.kubernetes.io/ssl-redirect: "false"
123 | nginx.ingress.kubernetes.io/rewrite-target: /$2
124 | paths:
125 | - /alertmanager(/|$)(.*)
126 | hosts:
127 | - dev.dynamic.cluster109.local
128 |
129 | alertmanagerSpec:
130 | ## Storage is the definition of how storage will be used by the Alertmanager instances.
131 | ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/user-guides/storage.md
132 | ##
133 | storage:
134 | volumeClaimTemplate:
135 | metadata:
136 | name: alert
137 | spec:
138 | storageClassName: sc-metrics
139 | accessModes: [ "ReadWriteOnce" ]
140 | resources:
141 | requests:
142 | storage: 8Gi
143 |
144 | # GRAFANA SECTION
145 | grafana:
146 | ## In order to render HTML and Javascript in a text panel without being sanitized
147 | ## enable the `disable_sanitize_html` settings in Grafana ini file
148 | grafana.ini:
149 | ## If you have Ingress, you need to change the root_url to match ingress path
150 | server:
151 | root_url: http://localhost:3000/grafana
152 |
153 | ## Enable persistence using Persistent Volume Claims
154 | ## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
155 | ##
156 | persistence:
157 | type: pvc
158 | enabled: true
159 | storageClassName: sc-metrics
160 | accessModes:
161 | - ReadWriteOnce
162 | size: 10Gi
163 |
164 | ingress:
165 | ## If true, Grafana Ingress will be created
166 | ##
167 | enabled: true
168 |
169 | annotations:
170 | nginx.ingress.kubernetes.io/ssl-redirect: "false"
171 | nginx.ingress.kubernetes.io/rewrite-target: /$2
172 | path: /grafana(/|$)(.*)
173 | hosts:
174 | - dev.dynamic.cluster109.local
175 |
176 | # NDP SECTION
177 | ## Configuration for node-problem-detector subchart
178 | node-problem-detector:
179 | install: true
180 | ````
181 |
182 | # Add your Grafana Dashboards and Prometheus rules
183 |
184 | OpenEBS monitoring stack come with Grafana dashboards and Prometheus rules, but it's possible to add your own by extending the monitoring stack.
185 |
186 | In the monitoring stack, there is a folder named `dashboards` that contains Grafana dashboards and the folder `rules` contains Prometheus rules. To extends the stack, we will have the folder structure based on the structure within the monitoring stack.
187 |
188 | Our umbrella chart folder structure will look like that :
189 |
190 | | Folder/File | Description |
191 | | ------ | ------ |
192 | | charts | Contains your chart dependencies (auto-generated with helm) |
193 | | dashboards | Contains all your Grafana dashboards (json format) |
194 | | rules | Contains all your Prometheus rules (json or yaml format) |
195 | | templates | helm templates to include your dashboards and rules into OpenEBS monitoring stack|
196 | | Chart.yaml | Contains your chart identification with a dependency to OpenEBS monitoring stack |
197 | | values.yaml | Contains all your settings values |
198 |
199 | Here a example of umbrella chart using external Grafana dashboards and Prometheus rules. You can separate your files with sub folders to simplify and regroup them. The helm templates will check within the sub folders for files to import.
200 |
201 | ````
202 | 📦umbrella
203 | ┣ 📂charts
204 | ┃ ┗ 📜monitoring-0.4.9.tgz
205 | ┣ 📂dashboards
206 | ┃ ┣ 📂custom
207 | ┃ ┃ ┣ 📜k8s-persistence-volumes.json
208 | ┃ ┃ ┗ 📜node-exporter-full.json
209 | ┃ ┗ 📂kafka
210 | ┃ ┃ ┣ 📜confluent-open-source-grafana-dashboard.json
211 | ┣ 📂rules
212 | ┃ ┗ 📂custom
213 | ┃ ┃ ┗ 📜instance-down.json
214 | ┣ 📂templates
215 | ┃ ┣ 📜dashboards-json-configmap.yaml
216 | ┃ ┣ 📜prometheusRules.yaml
217 | ┃ ┗ 📜_helpers.tpl
218 | ┣ 📜Chart.lock
219 | ┣ 📜Chart.yaml
220 | ┗ 📜values.yaml
221 | ````
222 |
223 | ### Helm templates to import your files into OpenEBS monitoring stack
224 |
225 | Here the content of the files into templates folder. Those files are based on those within the monitoring stack. You can customize it to fit your needs or use it as is.
226 |
227 | | File | Description |
228 | | ------ | ------ |
229 | | _helpers.tpl | Helm template helper |
230 | | dashboard-json-configmap.yaml | Contains the logic to add Grafana dashboards to OpenEBS monitoring stack |
231 | | prometheusRules.yaml | Contains the logic to add Prometheus rules to OpenEBS monitoring stack |
232 |
233 | #### _helpers.tpl
234 | ````yaml
235 | {{/* vim: set filetype=mustache: */}}
236 | {{/*
237 | Expand the name of the chart.
238 | */}}
239 | {{- define "monitoring.name" -}}
240 | {{- default .Chart.Name .Values.nameOverride | trunc 50 | trimSuffix "-" }}
241 | {{- end }}
242 |
243 | {{/*
244 | Create a default fully qualified app name.
245 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
246 | If release name contains chart name it will be used as a full name.
247 | */}}
248 | {{- define "monitoring.fullname" -}}
249 | {{- if .Values.fullnameOverride }}
250 | {{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" }}
251 | {{- else }}
252 | {{- $name := default .Chart.Name .Values.nameOverride }}
253 | {{- if contains $name .Release.Name }}
254 | {{- .Release.Name | trunc 26 | trimSuffix "-" }}
255 | {{- else }}
256 | {{- printf "%s-%s" .Release.Name $name | trunc 26 | trimSuffix "-" }}
257 | {{- end }}
258 | {{- end }}
259 | {{- end }}
260 |
261 | {{/*
262 | Allow the release namespace to be overridden for multi-namespace deployments in combined charts
263 | */}}
264 | {{- define "monitoring.namespace" -}}
265 | {{- if .Values.namespaceOverride -}}
266 | {{- .Values.namespaceOverride -}}
267 | {{- else -}}
268 | {{- .Release.Namespace -}}
269 | {{- end -}}
270 | {{- end -}}
271 |
272 |
273 | {{/*
274 | Create chart name and version as used by the chart label.
275 | */}}
276 | {{- define "monitoring.chart" -}}
277 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
278 | {{- end }}
279 |
280 | {{/*
281 | Common labels
282 | */}}
283 | {{- define "monitoring.labels" -}}
284 | helm.sh/chart: {{ include "monitoring.chart" . }}
285 | {{ include "monitoring.selectorLabels" . }}
286 | {{- if .Chart.AppVersion }}
287 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
288 | {{- end }}
289 | app.kubernetes.io/managed-by: {{ .Release.Service }}
290 | {{- end }}
291 |
292 | {{/*
293 | Selector labels
294 | */}}
295 | {{- define "monitoring.selectorLabels" -}}
296 | app.kubernetes.io/name: {{ include "monitoring.name" . }}
297 | app.kubernetes.io/instance: {{ .Release.Name }}
298 | release: {{ $.Release.Name | quote }}
299 | {{- end }}
300 |
301 | {{/*
302 | Template to support multiple levels of sub-charts
303 |
304 | Call a template from the context of a subchart.
305 |
306 | Usage:
307 | {{ include "call-nested" (list . "" "") }}
308 | */}}
309 | {{- define "call-nested" }}
310 | {{- $dot := index . 0 }}
311 | {{- $subchart := index . 1 | splitList "." }}
312 | {{- $template := index . 2 }}
313 | {{- $values := $dot.Values }}
314 | {{- range $subchart }}
315 | {{- $values = index $values . }}
316 | {{- end }}
317 | {{- include $template (dict "Chart" (dict "Name" (last $subchart)) "Values" $values "Release" $dot.Release "Capabilities" $dot.Capabilities) }}
318 | {{- end }}
319 | ````
320 |
321 | #### dashboard-json-configmap.yaml
322 | ````yaml
323 | {{- $grafanaSidecarDashboardsLabel := index .Values "monitoring" "kube-prometheus-stack" "grafana" "sidecar" "dashboards" "label" }}
324 | {{- $files := .Files.Glob "dashboards/**.json" }}
325 | {{- if $files }}
326 | {{- range $fileName, $fileContents := $files }}
327 | {{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $fileName "${2}" }}
328 | apiVersion: v1
329 | kind: ConfigMap
330 | metadata:
331 | name: {{ lower (printf "%s-%s" (include "monitoring.fullname" $) $dashboardName) | trunc 63 | trimSuffix "-" }}
332 | namespace: {{ template "monitoring.namespace" $ }}
333 | labels:
334 | {{ $grafanaSidecarDashboardsLabel }}: "1"
335 | app: {{ template "monitoring.name" $ }}-grafana
336 | {{ include "monitoring.labels" $ | indent 4 }}
337 | data:
338 | {{ $dashboardName }}.json: {{ $.Files.Get $fileName | toPrettyJson }}
339 | ---
340 | {{- end }}
341 | {{- end }}
342 | ````
343 |
344 | #### prometheusRules.yaml
345 | ````yaml
346 | {{- $files := .Files.Glob "rules/**.json" }}
347 | {{- if $files }}
348 | {{- range $fileName, $fileContents := $files }}
349 | {{- $ruleName := regexReplaceAll "(^.*/)(.*)\\.json$" $fileName "${2}" }}
350 | apiVersion: monitoring.coreos.com/v1
351 | kind: PrometheusRule
352 | metadata:
353 | name: {{ lower (printf "%s-%s" (include "monitoring.name" $) $ruleName) | trunc 63 | trimSuffix "-" }}
354 | namespace: {{ template "monitoring.namespace" $ }}
355 | labels:
356 | app: {{ template "monitoring.name" $ }}
357 | {{ include "monitoring.labels" $ | indent 4 }}
358 | spec:
359 | {{ $.Files.Get $fileName | indent 2 }}
360 | ---
361 | {{- end }}
362 | {{- end }}
363 | ````
364 |
365 | Here a example of a custom Prometheus rules that you can add to the monitoring stack.
366 |
367 | #### instance-down.json
368 | ````json
369 | {
370 | "groups": [
371 | {
372 | "name": "Instances",
373 | "rules": [
374 | {
375 | "alert": "InstanceDown",
376 | "expr": "up == 0",
377 | "for": "10s",
378 | "labels": {
379 | "severity": "page"
380 | },
381 | "annotations": {
382 | "description": "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.",
383 | "summary": "Instance {{ $labels.instance }} down"
384 | }
385 | }
386 | ]
387 | }
388 | ]
389 | }
390 | ````
391 |
392 | # How to deploy the umbrella chart
393 |
394 | ### Download the dependencies
395 | The first step will be to download the dependencies by running this command in a terminal in the umbrella folder.
396 |
397 | ````console
398 | helm dep build
399 | ````
400 |
401 | If you had already ran that command and you changed the dependencies in Chart.yaml, you will have to download the new dependencies by running this command.
402 |
403 | ````console
404 | helm dep up
405 | ````
406 |
407 | You will obtain that folder structure
408 |
409 | ```
410 | 📦umbrella
411 | ┣ 📂charts
412 | ┃ ┗ 📜monitoring-0.4.8.tgz
413 | ┣ 📂templates
414 | ┣ 📜Chart.lock
415 | ┣ 📜Chart.yaml
416 | ┗ 📜values.yaml
417 | ```
418 |
419 | ### Install the chart
420 |
421 | #### From the umbrella folder
422 |
423 | In a terminal in the umbrella folder run this command :
424 |
425 | ```console
426 | helm install [RELEASE_NAME] . -n [NAMESPACE] --create-namespace
427 | ```
428 |
429 | ex :
430 | ````console
431 | helm install monitoring . -n monitoring --create-namespace
432 | ````
433 |
434 | #### From a helm chart repository
435 |
436 | In a terminal in the umbrella folder run this command :
437 |
438 | ```console
439 | helm install [RELEASE_NAME] [REPOSITORY]/[CHART_NAME] -n [NAMESPACE] --create-namespace
440 | ```
441 |
442 | ex :
443 | ````console
444 | helm install monitoring chartmuseum/monitoring-stack -n monitoring --create-namespace
445 | ````
446 |
--------------------------------------------------------------------------------
/docs/guide.md:
--------------------------------------------------------------------------------
1 | # Install openebs-addon-only
2 |
3 | ### Prerequisite
4 |
5 | - Already installed prometheus-operator stack
6 | - OpenEBS installed
7 |
8 | ---
9 | **NOTE**
10 |
11 | - To allow Prometheus to discover all `PodMonitors/ServiceMonitors`, without applying label filtering, you have to set `prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues` and `prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues` to `false`
12 |
13 | - Install grafana plugin
14 |
15 | - There are two plugins that we are using for OpenEBS dashboards.
16 |
17 | - [grafana-polystat-panel]([https://link](https://grafana.com/grafana/plugins/grafana-polystat-panel/))
18 |
19 | - [snuids-trafficlights-panel]([https://link](https://grafana.com/grafana/plugins/snuids-trafficlights-panel/))
20 |
21 | - To install these plugin, exec into the `grafana` container and run
22 | ```
23 | grafana-cli plugins install grafana-polystat-panel
24 | grafana-cli plugins install snuids-trafficlights-panel
25 | ```
26 | - Update Grafana configuration
27 |
28 | - Append the below configuration in the configmap in which Grafana initialisation is done or cm in which `grafana.ini` file is declared.
29 | ```console
30 | grafana.ini:
31 | --------------
32 | ...
33 | [panels]
34 | disable_sanitize_html = true
35 | ...
36 | ```
37 |
38 | ---
39 |
40 | ## Step by Step Process
41 |
42 | 1. **Update values.yaml**
43 |
44 | - Disable dependent chart(kube-prometheus-stack) by updating `kube-prometheus-stack.install` to `false`
45 | - If you have updated the label for Grafana sidecar container(`grafana-sc-dashboard`), then update `kube-prometheus-stack.grafana.sidecar.dashboards.label: `
46 | - Update `namespaceOverride` with the namespace name in which Prometheus stack is installed
47 | - After updating these specific values in values.yaml, these fields should look like this(example) :
48 | ```console
49 | ...
50 | namespaceOverride: "prometheus-operator"
51 | kube-prometheus-stack:
52 | install: false
53 | grafana:
54 | ## Sidecar container to load dashboard cm
55 | sidecar:
56 | dashboards:
57 | enabled: true
58 | # ConfigMaps with label below will be added to Grafana as dashboards.
59 | label: grafana_dashboard
60 |
61 |
62 | ...
63 | ```
64 |
65 |
66 | 2. **Install `monitoring` chart**
67 |
68 | ```console
69 | # Helm
70 | helm install -f values.yaml [RELEASE_NAME] monitoring/monitoring
71 | ```
72 |
73 | #### Helm Chart install with one line
74 |
75 | ```console
76 | #Helm
77 | helm install [RELEASE_NAME] monitoring/monitoring -n [PROMETHEUS-STACK-NAMESPACE] --set kube-prometheus-stack.install=false,kube-prometheus-stack.grafana.sidecar.dashboards.label=[UPDATED_LABEL]
78 | ```
79 |
80 | #### Verification
81 |
82 | - Verify `PodMonitors/ServiceMonitors` are installed
83 |
84 | ```console
85 | kubectl get servicemonitors -n prometheus-operator -l release="monitoring"
86 | NAME AGE
87 | monitoring-openebs-mayastor 33m
88 | ```
89 |
90 | - Verify `dashboards configmaps` are installed
91 |
92 | ```console
93 | kubectl get cm -n prometheus-operator -l release="monitoring"
94 | NAME DATA AGE
95 | monitoring-openebs-diskpool 1 37m
96 | ```
97 |
98 | - To see the dashboards, form the Grafana URL and open it in the browser
--------------------------------------------------------------------------------
/docs/metrics-csi.md:
--------------------------------------------------------------------------------
1 | # CSI metrics exposed
2 |
3 | Here is the list of csi volume metrics exposed by k8s:-
4 |
5 | ```
6 | kubelet_volume_stats_available_bytes
7 | kubelet_volume_stats_capacity_bytes
8 | kubelet_volume_stats_inodes
9 | kubelet_volume_stats_inodes_free
10 | kubelet_volume_stats_inodes_used
11 | kubelet_volume_stats_used_bytes
12 | ```
13 |
--------------------------------------------------------------------------------
/docs/metrics-lvm.md:
--------------------------------------------------------------------------------
1 | # Monitoring OpenEBS lvm-localpv volumes
2 |
3 | ## Metrics supported by lvm-localpv volumes as of the current release are:
4 |
5 | ### Logical volumes metrics:
6 |
7 | ```
8 | lvm_lv_health_status # LV health status: [-1: undefined], [0: ""], [1: partial], [2: refresh needed], [3: mismatches exist]
9 | lvm_lv_mda_total_size_bytes # LVM LV metadata size in bytes
10 | lvm_lv_mda_used_percent # LVM LV metadata used size in percentage(1-100)
11 | lvm_lv_permission # LV permissions: [-1: undefined], [0: unknown], [1: writeable], [2: read-only], [3: read-only-override]
12 | lvm_lv_raid_sync_action # For LV RAID, the current synchronization action being performed: [-1: undefined], [0: idle], [1: frozen], [2: resync], [3: recover], [4: check], [5: repair]
13 | lvm_lv_snap_percent # LVM LV snap used size in percentage(1-100)
14 | lvm_lv_total_size_bytes # LVM LV total size in bytes
15 | lvm_lv_used_percent # LVM LV used size in percentage(1-100)
16 | lvm_lv_when_full # For thin pools, behavior when full: [-1: undefined], [0: error], [1: queue]
17 | ```
18 |
19 | ### Physical volume metrics:
20 |
21 | ```
22 | lvm_pv_device_size_bytes # LVM PV underlying device size in bytes
23 | lvm_pv_free_size_bytes # LVM PV free size in bytes
24 | lvm_pv_mda_free_size_bytes # LVM PV device free metadata area space in bytes
25 | lvm_pv_mda_total_size_bytes # LVM PV device smallest metadata area size in bytes
26 | lvm_pv_total_size_bytes # LVM PV total size in bytes
27 | lvm_pv_used_size_bytes # LVM PV used size in bytes
28 | ```
29 |
30 | ### Volume group metrics:
31 |
32 | ```
33 | lvm_vg_allocation_policy # VG allocation policy: [-1: undefined], [0: normal], [1: contiguous], [2: cling], [3: anywhere], [4: inherited]
34 | lvm_vg_free_size_bytes # LVM VG free size in bytes
35 | lvm_vg_lv_count # Number of LVs in VG
36 | lvm_vg_max_lv_count # Maximum number of LVs allowed in VG or 0 if unlimited
37 | lvm_vg_max_pv_count # Maximum number of PVs allowed in VG or 0 if unlimited
38 | lvm_vg_mda_count # Number of metadata areas on this VG
39 | lvm_vg_mda_free_size_bytes # Free metadata area space for this VG in bytes
40 | lvm_vg_mda_total_size_bytes # Size of smallest metadata area for this VG in bytes
41 | lvm_vg_mda_used_count # Number of metadata areas in use on this VG
42 | lvm_vg_missing_pv_count # Number of PVs in VG which are missing
43 | lvm_vg_permission # VG permissions: [-1: undefined], [0: writeable], [1: read-only]
44 | lvm_vg_pv_count # Number of PVs in VG
45 | lvm_vg_snap_count # Number of snapshots in VG
46 | lvm_vg_total_size_bytes # LVM VG total size in bytes
47 |
48 | ```
49 |
--------------------------------------------------------------------------------
/docs/metrics-node-problem-detector.md:
--------------------------------------------------------------------------------
1 | # node-problem-detector metrics
2 |
3 | Here is a list of metrics exported by node-problem-detector metrics when kernel-monitor and docker-monitor is only enabled. Other rules can also be monitored by adding them to the `log_monitors` field in the values.yaml used by [node-problem-detector](https://git.app.uib.no/caleno/helm-charts/-/blob/master/stable/node-problem-detector/values.yaml). Accordingly the metrics will also appear.
4 |
5 | ## Metrics by enabling kernel-monitor
6 |
7 | ```
8 | problem_counter{reason="OOMKilling"} # system logs with pattern- "Killed process \\d+ (.+) total-vm:\\d+kB, anon-rss:\\d+kB, file-rss:\\d+kB._"
9 | problem_counter{reason="TaskHung"} # system logs with pattern- "task [\\S ]+:\\w+ blocked for more than \\w+ seconds\\."
10 | problem_counter{reason="UnregisterNetDevice"} # system logs with pattern- "unregister_netdevice: waiting for \\w+ to become free. Usage count = \\d+"
11 | problem_counter{reason="KernelOops"} # system logs with pattern- "BUG: unable to handle kernel NULL pointer dereference at ._"
12 | problem_counter{reason="KernelOops"} # system logs with pattern- "divide error: 0000 \\[#\\d+\\] SMP"
13 | problem_counter{reason="Ext4Error"} # system logs with pattern- "EXT4-fs error ._"
14 | problem_counter{reason="Ext4Warning"} # system logs with pattern- "EXT4-fs warning ._"
15 | problem_counter{reason="IOError"} # system logs with pattern- "Buffer I/O error ._"
16 | problem_counter{reason="MemoryReadError"} # system logs with pattern- "CE memory read error ._"
17 | problem_counter{reason="AUFSUmountHung"} # system logs with pattern- "task umount\\.aufs:\\w+ blocked for more than \\w+ seconds\\."
18 | problem_counter{reason="DockerHung"} # system logs with pattern- "task docker:\\w+ blocked for more than \\w+ seconds\\."
19 | problem_counter{reason="FilesystemIsReadOnly"} # system logs with pattern- "Remounting filesystem read-only"
20 | ```
21 |
22 | ## Metrics by enabling docker-monitor
23 |
24 | ```
25 | problem_counter{reason="CorruptDockerImage"} # system logs with pattern- "Error trying v2 registry: failed to register layer: rename /var/lib/docker/image/(.+) /var/lib/docker/image/(.+): directory not empty._"
26 | problem_counter{reason="CorruptDockerOverlay2"} # system logs with pattern- "returned error: readlink /var/lib/docker/overlay2._: invalid argument.\*"
27 | problem_counter{reason="DockerContainerStartupFailure"} # system logs with pattern- "OCI runtime start failed: container process is already dead: unknown"
28 | ```
29 |
--------------------------------------------------------------------------------
/docs/openebs-mixin-user-guide.md:
--------------------------------------------------------------------------------
1 | # Install openebs-mixin
2 |
3 | ---
4 | ### Different scenarios to use openebs-mixin
5 |
6 | 1. Install openebs-mixin with monitoring written in jsonnet.
7 | 2. Install openebs-mixin in existing prometheus stack.
8 |
9 | ---
10 | ## Install openebs-mixin with monitoring written in jsonnet.
11 | To install kube-prometheus stack with openebs-addons(serviceMonitors, grafana dashboards and alert rules).
12 |
13 | ### Prerequisite
14 |
15 | - OpenEBS installed
16 |
17 | #### Step by Step Process
18 |
19 | 1. **Configuration**
20 | The available fields and their default values are present in [config.libsonnet](../jsonnet/config.libsonnet). To update the configuration of mixin, you need to override the configuration through config.libsonnet.
21 | ```
22 | . . .
23 | // import openebs-mixin and override configurations
24 | openebsMixin: (import './openebs-mixin/mixin.libsonnet') {
25 | _config+:: {
26 | dashboards+: {
27 | lvmLocalPV: $._config.openebsMonitoringAddon.lvmLocalPV.dashboards,
28 | },
29 | alertRules+: {
30 | lvmLocalPV: $._config.openebsMonitoringAddon.lvmLocalPV.alertRules,
31 | },
32 | },
33 | },
34 | . . .
35 |
36 | ```
37 |
38 | 2. **Install kube-prometheus stack with monitoring addons**
39 | To generate manifest to install monitoring in kubernetes cluster, you need to run [main.jsonnet](../jsonnet/main.jsonnet). To generate manifests, please follow the steps listed over [here](../jsonnet/README.md).
40 | ```
41 | . . .
42 | local config = import './config.libsonnet';
43 | local openebsMixin = config.openebsMixin;
44 |
45 | local kp =
46 | config.kp {
47 | values+:: {
48 | grafana+: {
49 | dashboards+: openebsMixin.grafanaDashboards,
50 | },
51 | };
52 |
53 | // kube-prometheus stack
54 | { 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
55 | {
56 | ['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
57 | for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
58 | } +
59 | // serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
60 | { 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
61 | { 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
62 | { 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
63 | { ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
64 | { ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
65 | { ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
66 | { ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
67 | { ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
68 |
69 |
70 | // servicemonitor, podmonitor and prometheusrules for different casTypes of openebs
71 | { ['openebs-addons/openebs-servicemonitor-' + casType]: serviceMonitor.serviceMonitors[casType] for casType in std.objectFields(serviceMonitor.serviceMonitors) } +
72 | { ['openebs-addons/openebs-podmonitor-' + casType]: podMonitors.podMonitors[casType] for casType in std.objectFields(podMonitors.podMonitors) } +
73 | // to enable alert rules
74 | { ['openebs-addons/openebs-rule-' + name]: rules.prometheusRules[name] for name in std.objectFields(rules.prometheusRules) }
75 |
76 | ```
77 | ---
78 |
79 | ## Install openebs-mixin in existing prometheus stack.
80 | Setup Grafana dashboards and alert rules for OpenEBS monitoring.
81 | ### Prerequisite
82 |
83 | - OpenEBS installed
84 | - Prometheus stack installed
85 | - ServiceMonitors and PodMonitors are already installed for different cas types.
86 |
87 | #### Step by Step Process
88 |
89 | 1. **Override openebs-mixin configuration**
90 | The available fields and their default values are present in [config.libsonnet](../jsonnet/openebs-mixin/config.libsonnet). To update the configuration of mixin, you need to override the configuration.
91 | ```
92 | . . .
93 | // import openebs-mixin and override configurations
94 | local openebsMixin=(import 'kube-prometheus/lib/mixin.libsonnet')({
95 | name: 'openebsMixin',
96 | mixin: (import './openebs-mixin/mixin.libsonnet'){
97 | _config+:: {
98 | dashboards+: {
99 | mayastor: true,
100 | lvmLocalPV: false,
101 | . . .
102 | },
103 | alertRules+: {
104 | mayastor: true,
105 | lvmLocalPV: true,
106 | . . .
107 | },
108 | }
109 | },
110 | });
111 | . . .
112 | ```
113 | 2. **Install openebs-mixin**
114 | To create a openebs-mixin object that has Prometheus rules and Grafana dashboards:
115 | ```
116 | local openebsMixin=(import 'kube-prometheus/lib/mixin.libsonnet')({
117 | name: 'openebsMixin',
118 | mixin: (import './openebs-mixin/mixin.libsonnet'),
119 | });
120 | ```
121 | The openebsMixin object will have two objects - `prometheusRules` and `grafanaDashboards`. The `grafanaDashboards` object will be needed to be added to the dashboards field as in the example below:
122 | ```
123 | . . .
124 | values+:: {
125 | grafana+: {
126 | // To install openebs dashboards
127 | dashboards+: openebsMixin.grafanaDashboards,
128 | },
129 | }
130 | . . .
131 | ```
132 | The `prometheusRules` object should be defined as its own jsonnet object.
133 | ```
134 | . . .
135 | // To generate prometheusRule object
136 | { 'openebs-addons/openebs-mixin-prometheus-rules': openebsMixin.prometheusRules }
137 | . . .
138 | ```
--------------------------------------------------------------------------------
/jsonnet/Makefile:
--------------------------------------------------------------------------------
1 | SHELL=/usr/bin/env bash -o pipefail
2 |
3 | BIN_DIR?=$(shell pwd)/tmp/bin
4 |
5 | JB_BIN=$(BIN_DIR)/jb
6 | JSONNET_BIN=$(BIN_DIR)/jsonnet
7 | JSONNETLINT_BIN=$(BIN_DIR)/jsonnet-lint
8 | JSONNETFMT_BIN=$(BIN_DIR)/jsonnetfmt
9 | TOOLING=$(JB_BIN) $(JSONNET_BIN) $(JSONNETLINT_BIN) $(JSONNETFMT_BIN)
10 |
11 | JSONNETFMT_ARGS=-n 2 --max-blank-lines 2 --string-style s --comment-style s
12 |
13 | all: lint fmt
14 |
15 | .PHONY: clean
16 | clean:
17 | # Remove all files and directories ignored by git.
18 | git clean -Xfd .
19 |
20 | .PHONY: fmt
21 | fmt: $(JSONNETFMT_BIN)
22 | find . -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
23 | xargs -n 1 -- $(JSONNETFMT_BIN) $(JSONNETFMT_ARGS) -i
24 |
25 | .PHONY: lint
26 | lint: $(JSONNETLINT_BIN)
27 | find . -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
28 | xargs -n 1 -- $(JSONNETLINT_BIN)
29 |
30 |
31 | $(BIN_DIR):
32 | mkdir -p $(BIN_DIR)
33 |
34 | $(TOOLING): $(BIN_DIR)
35 | @echo Installing tools from buildscripts/tools.go
36 | @cd buildscripts && cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go build -modfile=go.mod -o $(BIN_DIR) %
37 |
--------------------------------------------------------------------------------
/jsonnet/buildscripts/go.mod:
--------------------------------------------------------------------------------
1 | module _ // go.mod created for tooling dependencies
2 |
3 | go 1.19
4 |
5 | require (
6 | github.com/google/go-jsonnet v0.20.0
7 | github.com/jsonnet-bundler/jsonnet-bundler v0.4.0
8 | )
9 |
10 | require (
11 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
12 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
13 | github.com/fatih/color v1.12.0 // indirect
14 | github.com/mattn/go-colorable v0.1.8 // indirect
15 | github.com/mattn/go-isatty v0.0.12 // indirect
16 | github.com/pkg/errors v0.8.0 // indirect
17 | golang.org/x/sys v0.1.0 // indirect
18 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
19 | gopkg.in/yaml.v2 v2.4.0 // indirect
20 | sigs.k8s.io/yaml v1.2.0 // indirect
21 | )
22 |
--------------------------------------------------------------------------------
/jsonnet/buildscripts/go.sum:
--------------------------------------------------------------------------------
1 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
2 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
3 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
4 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
5 | github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
10 | github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
11 | github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
12 | github.com/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g=
13 | github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA=
14 | github.com/jsonnet-bundler/jsonnet-bundler v0.4.0 h1:4BKZ6LDqPc2wJDmaKnmYD/vDjUptJtnUpai802MibFc=
15 | github.com/jsonnet-bundler/jsonnet-bundler v0.4.0/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU=
16 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
17 | github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
18 | github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
19 | github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
20 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
21 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
22 | github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
23 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
24 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
26 | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
27 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
28 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
29 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
30 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
31 | golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
32 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
33 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
34 | golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
35 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
36 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
37 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
38 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
39 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
40 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
41 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
42 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
43 | sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
44 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
45 |
--------------------------------------------------------------------------------
/jsonnet/buildscripts/tools.go:
--------------------------------------------------------------------------------
1 | //+build tools
2 |
3 | // Package tools tracks dependencies for tools that used in the build process.
4 | // See https://github.com/golang/go/wiki/Modules
5 | package tools
6 |
7 | import (
8 | _ "github.com/google/go-jsonnet/cmd/jsonnet"
9 | _ "github.com/google/go-jsonnet/cmd/jsonnet-lint"
10 | _ "github.com/google/go-jsonnet/cmd/jsonnetfmt"
11 | _ "github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb"
12 | )
13 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/Makefile:
--------------------------------------------------------------------------------
1 | JSONNET_ARGS := -n 2 --max-blank-lines 2 --string-style s --comment-style s
2 | ifneq (,$(shell which jsonnetfmt))
3 | JSONNET_FMT_CMD := jsonnetfmt
4 | else
5 | JSONNET_FMT_CMD := jsonnet
6 | JSONNET_FMT_ARGS := fmt $(JSONNET_ARGS)
7 | endif
8 | JSONNET_FMT := $(JSONNET_FMT_CMD) $(JSONNET_FMT_ARGS)
9 |
10 | dashboardsDirPath=../../deploy/charts/dashboards
11 | rulessDirPath=../../deploy/charts/rules
12 |
13 | all: fmt generate lint
14 |
15 | fmt:
16 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
17 | xargs -n 1 -- $(JSONNET_FMT) -i
18 |
19 | generate: build.sh
20 | bash build.sh $<
21 |
22 | lint:
23 | find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
24 | while read f; do \
25 | $(JSONNET_FMT) "$$f" | diff -u "$$f" -; \
26 | done
27 |
28 | clean:
29 | rm -rf $(dashboardsDirPath) $(rulessDirPath)
30 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/README.md:
--------------------------------------------------------------------------------
1 | # openebs mixin
2 |
3 | A set of Grafana dashboards and Prometheus alerts for openebs.
4 |
5 | ## Generate dashboards and rules
6 |
7 | You can manually generate the alerts, dashboards and rules files.
8 |
9 | #### Steps:
10 |
11 | 1. Install `jsonnet` and `jb`
12 | ```
13 | $ go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
14 | $ sudo apt-get install jsonnet
15 | ```
16 |
17 | 2. Then, grab the mixin and its dependencies:
18 |
19 | ```
20 | $ git clone https://github.com/openebs/monitoring
21 | $ cd monitoring/jsonnet/openebs-mixin
22 | $ jb install
23 | ```
24 |
25 | 3. Update the dashboards and rules directory path in `build.sh`
26 | ```
27 | dashboardsDirPath = ''
28 | rulesDirPath = ''
29 | ```
30 |
31 | 4. Finally, build the mixin:
32 |
33 | ```
34 | $ make generate
35 | ```
36 |
37 | The files in `rulesDirPath` contain Prometheus-based alert rules for OpenEBS. These files will be aggregated to form a prometheusRule yaml that need to be imported into your Prometheus instance.
38 | Similarly, the files in `dashboardsDirPath` are dashboard json files that need to be imported into your Grafana instance.
39 |
40 | ## Configuration
41 |
42 | The available fields and their default values are present in `config.libsonnet`.
43 |
44 | ```
45 | {
46 | // openebs-mixin configurations
47 | _config+:: {
48 | // Configuration to set which cas types is installed. Based on this, dashboards and alert rules configuration will be set.
49 | casTypes: {
50 | mayastor: true,
51 | lvmLocalPV: true,
52 | zfsLocalPV: true,
53 | },
54 | // dashboards configuration. If set, then dashboards json will be generated.
55 | dashboards: {
56 | mayastor: $._config.casTypes.mayastor
57 | lvmLocalPV: $._config.casTypes.lvmLocalPV,
58 | zfsLocalPV: $._config.casTypes.zfsLocalPV,
59 | npd: true,
60 | },
61 | // AlertRules configuration. If set, then rules json will be generated.
62 | alertRules: {
63 | lvmLocalPV: $._config.casTypes.lvmLocalPV,
64 | volume: $._config.casTypes.lvmLocalPV,
65 | npd: true,
66 | },
67 | },
68 | }
69 | ```
70 | ---
71 |
72 | ## How to use openebs-mixin?
73 | Please visit the [user guide](../../docs/openebs-mixin-user-guide.md) for detailed instructions.
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 |
4 | set -e
5 | set -x
6 | # only exit with zero if all commands of the pipeline exit successfully
7 | set -o pipefail
8 |
9 | dashboardsDirPath=../../deploy/charts/dashboards
10 | rulesDirPath=../../deploy/charts/rules
11 |
12 | generateDashboards(){
13 | rm -rf $dashboardsDirPath
14 | mkdir -p $dashboardsDirPath
15 | jsonnet -J vendor -m $dashboardsDirPath lib/dashboards.jsonnet
16 | dashboardsFolder=(npd lvmLocalPV zfsLocalPV mayastor)
17 | for i in ${dashboardsFolder[@]}
18 | do
19 | x=`echo $i | awk '{print tolower($0)}'`
20 | mkdir -p $dashboardsDirPath/$i
21 | find ./$dashboardsDirPath -type f -name "*$x*" |xargs -I{} sh -c "mv {} $dashboardsDirPath/$i/"
22 | done
23 | }
24 |
25 | generateRules(){
26 | rm -rf $rulesDirPath
27 | mkdir -p $rulesDirPath
28 | jsonnet -J vendor -m $rulesDirPath lib/rules.jsonnet
29 | rulesFolder=(volume npd lvmLocalPV)
30 | for i in ${rulesFolder[@]}
31 | do
32 | x=`echo $i | awk '{print tolower($0)}'`
33 | mkdir -p $rulesDirPath/$i
34 | find ./$rulesDirPath -type f -name "*$x*" |xargs -I{} sh -c "mv {} $rulesDirPath/$i/"
35 | done
36 | }
37 |
38 | generateDashboards;
39 | generateRules;
40 |
41 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/config.libsonnet:
--------------------------------------------------------------------------------
1 | {
2 | // openebs-mixin configurations
3 | _config+:: {
4 | // Configuration to set which cas types is installed. Based on this, dashboards and alert rules configuration will be set.
5 | casTypes: {
6 | lvmLocalPV: true,
7 | zfsLocalPV: true,
8 | mayastor: true,
9 | },
10 |
11 | // dashboards configuration. If set, then dashboards json will be generated.
12 | dashboards: {
13 | lvmLocalPV: $._config.casTypes.lvmLocalPV,
14 | zfsLocalPV: $._config.casTypes.zfsLocalPV,
15 | npd: true,
16 | mayastor: $._config.casTypes.mayastor,
17 | },
18 | // AlertRules configuration. If set, then rules json will be generated.
19 | alertRules: {
20 | lvmLocalPV: $._config.casTypes.lvmLocalPV,
21 | volume: $._config.casTypes.lvmLocalPV,
22 | npd: true,
23 | },
24 | },
25 | }
26 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/dashboards/dashboards.libsonnet:
--------------------------------------------------------------------------------
1 | // Populate grafanaDashboards object
2 | function(param) {
3 | local dashboard = self,
4 | _config+:: param,
5 | grafanaDashboards+:: {
6 | [if dashboard._config.dashboards.lvmLocalPV then 'lvmlocalpv-pool.json']: import './openebs/lvmlocalpv-pool.json',
7 | [if dashboard._config.dashboards.zfsLocalPV then 'zfslocalpv.json']: import './openebs/zfslocalpv.json',
8 | [if dashboard._config.dashboards.mayastor then 'mayastor-diskpool.json']: import './mayastor/mayastor-diskpool.json',
9 | [if dashboard._config.dashboards.mayastor then 'mayastor-volume.json']: import './mayastor/mayastor-volume.json',
10 | [if dashboard._config.dashboards.mayastor then 'mayastor-volume-replica.json']: import './mayastor/mayastor-volume-replica.json',
11 | [if dashboard._config.dashboards.npd then 'npd-node-volume-problem.json']: import './npd/npd-node-volume-problem.json',
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/dashboards/mayastor/mayastor-volume-replica.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "grafana",
8 | "uid": "-- Grafana --"
9 | },
10 | "enable": true,
11 | "hide": true,
12 | "iconColor": "rgba(0, 211, 255, 1)",
13 | "name": "Annotations & Alerts",
14 | "type": "dashboard"
15 | }
16 | ]
17 | },
18 | "editable": true,
19 | "fiscalYearStartMonth": 0,
20 | "graphTooltip": 0,
21 | "id": 43,
22 | "links": [],
23 | "panels": [
24 | {
25 | "datasource": {
26 | "type": "prometheus",
27 | "uid": "$datasource"
28 | },
29 | "fieldConfig": {
30 | "defaults": {
31 | "color": {
32 | "mode": "palette-classic"
33 | },
34 | "custom": {
35 | "axisBorderShow": false,
36 | "axisCenteredZero": false,
37 | "axisColorMode": "text",
38 | "axisLabel": "",
39 | "axisPlacement": "auto",
40 | "barAlignment": 0,
41 | "drawStyle": "line",
42 | "fillOpacity": 10,
43 | "gradientMode": "none",
44 | "hideFrom": {
45 | "legend": false,
46 | "tooltip": false,
47 | "viz": false
48 | },
49 | "insertNulls": false,
50 | "lineInterpolation": "linear",
51 | "lineStyle": {
52 | "fill": "solid"
53 | },
54 | "lineWidth": 1,
55 | "pointSize": 5,
56 | "scaleDistribution": {
57 | "type": "linear"
58 | },
59 | "showPoints": "never",
60 | "spanNulls": false,
61 | "stacking": {
62 | "group": "A",
63 | "mode": "none"
64 | },
65 | "thresholdsStyle": {
66 | "mode": "off"
67 | }
68 | },
69 | "mappings": [],
70 | "thresholds": {
71 | "mode": "absolute",
72 | "steps": [
73 | {
74 | "color": "green",
75 | "value": null
76 | }
77 | ]
78 | },
79 | "unit": "iops"
80 | },
81 | "overrides": []
82 | },
83 | "gridPos": {
84 | "h": 8,
85 | "w": 12,
86 | "x": 0,
87 | "y": 0
88 | },
89 | "id": 1,
90 | "options": {
91 | "legend": {
92 | "calcs": [],
93 | "displayMode": "list",
94 | "placement": "bottom",
95 | "showLegend": true
96 | },
97 | "tooltip": {
98 | "mode": "multi",
99 | "sort": "none"
100 | }
101 | },
102 | "pluginVersion": "10.4.0",
103 | "targets": [
104 | {
105 | "datasource": {
106 | "uid": "$datasource"
107 | },
108 | "editorMode": "code",
109 | "exemplar": false,
110 | "expr": "irate(replica_num_read_ops{name=~\"$replica_name\"}[1m])",
111 | "interval": "",
112 | "legendFormat": "read",
113 | "range": true,
114 | "refId": "A"
115 | },
116 | {
117 | "datasource": {
118 | "type": "prometheus",
119 | "uid": "$datasource"
120 | },
121 | "editorMode": "code",
122 | "expr": "irate(replica_num_write_ops{name=~\"$replica_name\"}[1m])",
123 | "format": "time_series",
124 | "hide": false,
125 | "instant": false,
126 | "interval": "",
127 | "legendFormat": "write",
128 | "range": true,
129 | "refId": "B"
130 | }
131 | ],
132 | "title": "IOPS",
133 | "type": "timeseries"
134 | },
135 | {
136 | "datasource": {
137 | "type": "prometheus",
138 | "uid": "$datasource"
139 | },
140 | "fieldConfig": {
141 | "defaults": {
142 | "color": {
143 | "mode": "palette-classic"
144 | },
145 | "custom": {
146 | "axisBorderShow": false,
147 | "axisCenteredZero": false,
148 | "axisColorMode": "text",
149 | "axisLabel": "",
150 | "axisPlacement": "auto",
151 | "barAlignment": 0,
152 | "drawStyle": "line",
153 | "fillOpacity": 10,
154 | "gradientMode": "none",
155 | "hideFrom": {
156 | "legend": false,
157 | "tooltip": false,
158 | "viz": false
159 | },
160 | "insertNulls": false,
161 | "lineInterpolation": "linear",
162 | "lineStyle": {
163 | "fill": "solid"
164 | },
165 | "lineWidth": 1,
166 | "pointSize": 5,
167 | "scaleDistribution": {
168 | "type": "linear"
169 | },
170 | "showPoints": "never",
171 | "spanNulls": false,
172 | "stacking": {
173 | "group": "A",
174 | "mode": "none"
175 | },
176 | "thresholdsStyle": {
177 | "mode": "off"
178 | }
179 | },
180 | "mappings": [],
181 | "thresholds": {
182 | "mode": "absolute",
183 | "steps": [
184 | {
185 | "color": "green",
186 | "value": null
187 | }
188 | ]
189 | },
190 | "unit": "binBps"
191 | },
192 | "overrides": []
193 | },
194 | "gridPos": {
195 | "h": 8,
196 | "w": 12,
197 | "x": 12,
198 | "y": 0
199 | },
200 | "id": 2,
201 | "options": {
202 | "legend": {
203 | "calcs": [],
204 | "displayMode": "list",
205 | "placement": "bottom",
206 | "showLegend": true
207 | },
208 | "tooltip": {
209 | "mode": "multi",
210 | "sort": "none"
211 | }
212 | },
213 | "pluginVersion": "10.4.0",
214 | "targets": [
215 | {
216 | "datasource": {
217 | "uid": "$datasource"
218 | },
219 | "editorMode": "code",
220 | "exemplar": true,
221 | "expr": "irate(replica_bytes_read{name=~\"$replica_name\"}[1m])",
222 | "interval": "",
223 | "legendFormat": "read",
224 | "range": true,
225 | "refId": "A"
226 | },
227 | {
228 | "datasource": {
229 | "type": "prometheus",
230 | "uid": "$datasource"
231 | },
232 | "editorMode": "code",
233 | "expr": "irate(replica_bytes_written{name=~\"$replica_name\"}[1m])",
234 | "hide": false,
235 | "instant": false,
236 | "legendFormat": "write",
237 | "range": true,
238 | "refId": "B"
239 | }
240 | ],
241 | "title": "Throughput",
242 | "type": "timeseries"
243 | },
244 | {
245 | "datasource": {
246 | "type": "prometheus",
247 | "uid": "$datasource"
248 | },
249 | "fieldConfig": {
250 | "defaults": {
251 | "color": {
252 | "mode": "palette-classic"
253 | },
254 | "custom": {
255 | "axisBorderShow": false,
256 | "axisCenteredZero": false,
257 | "axisColorMode": "text",
258 | "axisLabel": "",
259 | "axisPlacement": "auto",
260 | "barAlignment": 0,
261 | "drawStyle": "line",
262 | "fillOpacity": 10,
263 | "gradientMode": "none",
264 | "hideFrom": {
265 | "legend": false,
266 | "tooltip": false,
267 | "viz": false
268 | },
269 | "insertNulls": false,
270 | "lineInterpolation": "linear",
271 | "lineStyle": {
272 | "fill": "solid"
273 | },
274 | "lineWidth": 1,
275 | "pointSize": 5,
276 | "scaleDistribution": {
277 | "type": "linear"
278 | },
279 | "showPoints": "never",
280 | "spanNulls": false,
281 | "stacking": {
282 | "group": "A",
283 | "mode": "none"
284 | },
285 | "thresholdsStyle": {
286 | "mode": "off"
287 | }
288 | },
289 | "mappings": [],
290 | "thresholds": {
291 | "mode": "absolute",
292 | "steps": [
293 | {
294 | "color": "green",
295 | "value": null
296 | }
297 | ]
298 | },
299 | "unit": "s"
300 | },
301 | "overrides": []
302 | },
303 | "gridPos": {
304 | "h": 8,
305 | "w": 12,
306 | "x": 6,
307 | "y": 8
308 | },
309 | "id": 3,
310 | "options": {
311 | "legend": {
312 | "calcs": [],
313 | "displayMode": "list",
314 | "placement": "bottom",
315 | "showLegend": true
316 | },
317 | "tooltip": {
318 | "mode": "multi",
319 | "sort": "none"
320 | }
321 | },
322 | "pluginVersion": "10.4.0",
323 | "targets": [
324 | {
325 | "datasource": {
326 | "uid": "$datasource"
327 | },
328 | "editorMode": "code",
329 | "exemplar": true,
330 | "expr": "((irate(replica_read_latency_us{name=~\"$replica_name\"}[1m]))/(irate(replica_num_read_ops{name=~\"$replica_name\"}[1m])))/1000000",
331 | "interval": "",
332 | "legendFormat": "read",
333 | "range": true,
334 | "refId": "A"
335 | },
336 | {
337 | "datasource": {
338 | "type": "prometheus",
339 | "uid": "$datasource"
340 | },
341 | "editorMode": "code",
342 | "expr": "((irate(replica_write_latency_us{name=~\"$replica_name\"}[1m]))/(irate(replica_num_write_ops{name=~\"$replica_name\"}[1m])))/1000000",
343 | "hide": false,
344 | "instant": false,
345 | "legendFormat": "write",
346 | "range": true,
347 | "refId": "B"
348 | }
349 | ],
350 | "title": "Latency",
351 | "type": "timeseries"
352 | }
353 | ],
354 | "refresh": "5s",
355 | "schemaVersion": 39,
356 | "tags": [
357 | "OpenEBS",
358 | "Mayastor"
359 | ],
360 | "templating": {
361 | "list": [
362 | {
363 | "current": {
364 | "selected": false,
365 | "text": "Prometheus",
366 | "value": "prometheus"
367 | },
368 | "hide": 0,
369 | "includeAll": false,
370 | "multi": false,
371 | "name": "datasource",
372 | "options": [],
373 | "query": "prometheus",
374 | "refresh": 1,
375 | "regex": "",
376 | "skipUrlSync": false,
377 | "type": "datasource"
378 | },
379 | {
380 | "current": {
381 | "selected": true,
382 | "text": [
383 | "All"
384 | ],
385 | "value": [
386 | "$__all"
387 | ]
388 | },
389 | "datasource": {
390 | "type": "prometheus",
391 | "uid": "${datasource}"
392 | },
393 | "definition": "label_values(replica_num_read_ops,name)",
394 | "hide": 0,
395 | "includeAll": true,
396 | "multi": true,
397 | "name": "replica_name",
398 | "options": [],
399 | "query": {
400 | "qryType": 1,
401 | "query": "label_values(replica_num_read_ops,name)",
402 | "refId": "PrometheusVariableQueryEditor-VariableQuery"
403 | },
404 | "refresh": 2,
405 | "regex": "",
406 | "skipUrlSync": false,
407 | "sort": 0,
408 | "type": "query"
409 | }
410 | ]
411 | },
412 | "time": {
413 | "from": "now-1h",
414 | "to": "now"
415 | },
416 | "timepicker": {},
417 | "timezone": "browser",
418 | "title": "OpenEBS / Replicated PV / Mayastor / Volume Replica",
419 | "uid": "fdl05xto1hn28e",
420 | "version": 6,
421 | "weekStart": ""
422 | }
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/dashboards/mayastor/mayastor-volume.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": {
7 | "type": "grafana",
8 | "uid": "-- Grafana --"
9 | },
10 | "enable": true,
11 | "hide": true,
12 | "iconColor": "rgba(0, 211, 255, 1)",
13 | "name": "Annotations & Alerts",
14 | "type": "dashboard"
15 | }
16 | ]
17 | },
18 | "editable": true,
19 | "fiscalYearStartMonth": 0,
20 | "graphTooltip": 0,
21 | "id": 42,
22 | "links": [],
23 | "panels": [
24 | {
25 | "datasource": {
26 | "type": "prometheus",
27 | "uid": "$datasource"
28 | },
29 | "fieldConfig": {
30 | "defaults": {
31 | "color": {
32 | "mode": "palette-classic"
33 | },
34 | "custom": {
35 | "axisBorderShow": false,
36 | "axisCenteredZero": false,
37 | "axisColorMode": "text",
38 | "axisLabel": "",
39 | "axisPlacement": "auto",
40 | "barAlignment": 0,
41 | "drawStyle": "line",
42 | "fillOpacity": 10,
43 | "gradientMode": "none",
44 | "hideFrom": {
45 | "legend": false,
46 | "tooltip": false,
47 | "viz": false
48 | },
49 | "insertNulls": false,
50 | "lineInterpolation": "linear",
51 | "lineStyle": {
52 | "fill": "solid"
53 | },
54 | "lineWidth": 1,
55 | "pointSize": 5,
56 | "scaleDistribution": {
57 | "type": "linear"
58 | },
59 | "showPoints": "never",
60 | "spanNulls": false,
61 | "stacking": {
62 | "group": "A",
63 | "mode": "none"
64 | },
65 | "thresholdsStyle": {
66 | "mode": "off"
67 | }
68 | },
69 | "mappings": [],
70 | "thresholds": {
71 | "mode": "absolute",
72 | "steps": [
73 | {
74 | "color": "green",
75 | "value": null
76 | }
77 | ]
78 | },
79 | "unit": "iops"
80 | },
81 | "overrides": []
82 | },
83 | "gridPos": {
84 | "h": 8,
85 | "w": 12,
86 | "x": 0,
87 | "y": 0
88 | },
89 | "id": 1,
90 | "options": {
91 | "legend": {
92 | "calcs": [],
93 | "displayMode": "list",
94 | "placement": "bottom",
95 | "showLegend": true
96 | },
97 | "tooltip": {
98 | "mode": "multi",
99 | "sort": "none"
100 | }
101 | },
102 | "pluginVersion": "10.4.0",
103 | "targets": [
104 | {
105 | "datasource": {
106 | "uid": "$datasource"
107 | },
108 | "editorMode": "code",
109 | "exemplar": false,
110 | "expr": "irate(volume_num_read_ops{pv_name=~\"$pv_name\"}[1m])",
111 | "interval": "",
112 | "legendFormat": "read",
113 | "range": true,
114 | "refId": "A"
115 | },
116 | {
117 | "datasource": {
118 | "type": "prometheus",
119 | "uid": "$datasource"
120 | },
121 | "editorMode": "code",
122 | "expr": "irate(volume_num_write_ops{pv_name=~\"$pv_name\"}[1m])",
123 | "format": "time_series",
124 | "hide": false,
125 | "instant": false,
126 | "interval": "",
127 | "legendFormat": "write",
128 | "range": true,
129 | "refId": "B"
130 | }
131 | ],
132 | "title": "IOPS",
133 | "type": "timeseries"
134 | },
135 | {
136 | "datasource": {
137 | "type": "prometheus",
138 | "uid": "$datasource"
139 | },
140 | "fieldConfig": {
141 | "defaults": {
142 | "color": {
143 | "mode": "palette-classic"
144 | },
145 | "custom": {
146 | "axisBorderShow": false,
147 | "axisCenteredZero": false,
148 | "axisColorMode": "text",
149 | "axisLabel": "",
150 | "axisPlacement": "auto",
151 | "barAlignment": 0,
152 | "drawStyle": "line",
153 | "fillOpacity": 10,
154 | "gradientMode": "none",
155 | "hideFrom": {
156 | "legend": false,
157 | "tooltip": false,
158 | "viz": false
159 | },
160 | "insertNulls": false,
161 | "lineInterpolation": "linear",
162 | "lineStyle": {
163 | "fill": "solid"
164 | },
165 | "lineWidth": 1,
166 | "pointSize": 5,
167 | "scaleDistribution": {
168 | "type": "linear"
169 | },
170 | "showPoints": "never",
171 | "spanNulls": false,
172 | "stacking": {
173 | "group": "A",
174 | "mode": "none"
175 | },
176 | "thresholdsStyle": {
177 | "mode": "off"
178 | }
179 | },
180 | "mappings": [],
181 | "thresholds": {
182 | "mode": "absolute",
183 | "steps": [
184 | {
185 | "color": "green",
186 | "value": null
187 | }
188 | ]
189 | },
190 | "unit": "binBps"
191 | },
192 | "overrides": []
193 | },
194 | "gridPos": {
195 | "h": 8,
196 | "w": 12,
197 | "x": 12,
198 | "y": 0
199 | },
200 | "id": 2,
201 | "options": {
202 | "legend": {
203 | "calcs": [],
204 | "displayMode": "list",
205 | "placement": "bottom",
206 | "showLegend": true
207 | },
208 | "tooltip": {
209 | "mode": "multi",
210 | "sort": "none"
211 | }
212 | },
213 | "pluginVersion": "10.4.0",
214 | "targets": [
215 | {
216 | "datasource": {
217 | "uid": "$datasource"
218 | },
219 | "editorMode": "code",
220 | "exemplar": true,
221 | "expr": "irate(volume_bytes_read{pv_name=~\"$pv_name\"}[1m])",
222 | "interval": "",
223 | "legendFormat": "read",
224 | "range": true,
225 | "refId": "A"
226 | },
227 | {
228 | "datasource": {
229 | "type": "prometheus",
230 | "uid": "$datasource"
231 | },
232 | "editorMode": "code",
233 | "expr": "irate(volume_bytes_written{pv_name=~\"$pv_name\"}[1m])",
234 | "hide": false,
235 | "instant": false,
236 | "legendFormat": "write",
237 | "range": true,
238 | "refId": "B"
239 | }
240 | ],
241 | "title": "Throughput",
242 | "type": "timeseries"
243 | },
244 | {
245 | "datasource": {
246 | "type": "prometheus",
247 | "uid": "$datasource"
248 | },
249 | "fieldConfig": {
250 | "defaults": {
251 | "color": {
252 | "mode": "palette-classic"
253 | },
254 | "custom": {
255 | "axisBorderShow": false,
256 | "axisCenteredZero": false,
257 | "axisColorMode": "text",
258 | "axisLabel": "",
259 | "axisPlacement": "auto",
260 | "barAlignment": 0,
261 | "drawStyle": "line",
262 | "fillOpacity": 10,
263 | "gradientMode": "none",
264 | "hideFrom": {
265 | "legend": false,
266 | "tooltip": false,
267 | "viz": false
268 | },
269 | "insertNulls": false,
270 | "lineInterpolation": "linear",
271 | "lineStyle": {
272 | "fill": "solid"
273 | },
274 | "lineWidth": 1,
275 | "pointSize": 5,
276 | "scaleDistribution": {
277 | "type": "linear"
278 | },
279 | "showPoints": "never",
280 | "spanNulls": false,
281 | "stacking": {
282 | "group": "A",
283 | "mode": "none"
284 | },
285 | "thresholdsStyle": {
286 | "mode": "off"
287 | }
288 | },
289 | "mappings": [],
290 | "thresholds": {
291 | "mode": "absolute",
292 | "steps": [
293 | {
294 | "color": "green",
295 | "value": null
296 | }
297 | ]
298 | },
299 | "unit": "s"
300 | },
301 | "overrides": []
302 | },
303 | "gridPos": {
304 | "h": 8,
305 | "w": 12,
306 | "x": 6,
307 | "y": 8
308 | },
309 | "id": 3,
310 | "options": {
311 | "legend": {
312 | "calcs": [],
313 | "displayMode": "list",
314 | "placement": "bottom",
315 | "showLegend": true
316 | },
317 | "tooltip": {
318 | "mode": "multi",
319 | "sort": "none"
320 | }
321 | },
322 | "pluginVersion": "10.4.0",
323 | "targets": [
324 | {
325 | "datasource": {
326 | "uid": "$datasource"
327 | },
328 | "editorMode": "code",
329 | "exemplar": true,
330 | "expr": "((irate(volume_read_latency_us{pv_name=~\"$pv_name\"}[1m]))/(irate(volume_num_read_ops{pv_name=~\"$pv_name\"}[1m])))/1000000",
331 | "interval": "",
332 | "legendFormat": "read",
333 | "range": true,
334 | "refId": "A"
335 | },
336 | {
337 | "datasource": {
338 | "type": "prometheus",
339 | "uid": "$datasource"
340 | },
341 | "editorMode": "code",
342 | "expr": "((irate(volume_write_latency_us{pv_name=~\"$pv_name\"}[1m]))/(irate(volume_num_write_ops{pv_name=~\"$pv_name\"}[1m])))/1000000",
343 | "hide": false,
344 | "instant": false,
345 | "legendFormat": "write",
346 | "range": true,
347 | "refId": "B"
348 | }
349 | ],
350 | "title": "Latency",
351 | "type": "timeseries"
352 | }
353 | ],
354 | "refresh": "5s",
355 | "schemaVersion": 39,
356 | "tags": [
357 | "OpenEBS",
358 | "Mayastor"
359 | ],
360 | "templating": {
361 | "list": [
362 | {
363 | "current": {
364 | "selected": false,
365 | "text": "Prometheus",
366 | "value": "prometheus"
367 | },
368 | "hide": 0,
369 | "includeAll": false,
370 | "multi": false,
371 | "name": "datasource",
372 | "options": [],
373 | "query": "prometheus",
374 | "refresh": 1,
375 | "regex": "",
376 | "skipUrlSync": false,
377 | "type": "datasource"
378 | },
379 | {
380 | "current": {
381 | "selected": true,
382 | "text": [
383 | "pvc-d070ac1c-6bb7-4ece-9893-5471c0c636a8"
384 | ],
385 | "value": [
386 | "pvc-d070ac1c-6bb7-4ece-9893-5471c0c636a8"
387 | ]
388 | },
389 | "datasource": {
390 | "type": "prometheus",
391 | "uid": "${datasource}"
392 | },
393 | "definition": "label_values(volume_num_read_ops,pv_name)",
394 | "hide": 0,
395 | "includeAll": true,
396 | "multi": true,
397 | "name": "pv_name",
398 | "options": [],
399 | "query": {
400 | "qryType": 1,
401 | "query": "label_values(volume_num_read_ops,pv_name)",
402 | "refId": "PrometheusVariableQueryEditor-VariableQuery"
403 | },
404 | "refresh": 2,
405 | "regex": "",
406 | "skipUrlSync": false,
407 | "sort": 0,
408 | "type": "query"
409 | }
410 | ]
411 | },
412 | "time": {
413 | "from": "now-1h",
414 | "to": "now"
415 | },
416 | "timepicker": {},
417 | "timezone": "browser",
418 | "title": "OpenEBS / Replicated PV / Mayastor / Volume",
419 | "uid": "fdl05gxyisqo0d",
420 | "version": 6,
421 | "weekStart": ""
422 | }
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/dashboards/npd/npd-node-volume-problem.json:
--------------------------------------------------------------------------------
1 | {
2 | "annotations": {
3 | "list": [
4 | {
5 | "builtIn": 1,
6 | "datasource": "-- Grafana --",
7 | "enable": true,
8 | "hide": true,
9 | "iconColor": "rgba(0, 211, 255, 1)",
10 | "name": "Annotations & Alerts",
11 | "type": "dashboard"
12 | }
13 | ]
14 | },
15 | "editable": true,
16 | "gnetId": null,
17 | "graphTooltip": 0,
18 | "id": 44,
19 | "links": [],
20 | "panels": [
21 | {
22 | "datasource": "null",
23 | "fieldConfig": {
24 | "defaults": {},
25 | "overrides": []
26 | },
27 | "gridPos": {
28 | "h": 7,
29 | "w": 24,
30 | "x": 0,
31 | "y": 0
32 | },
33 | "id": 10,
34 | "options": {
35 | "content": "# *Node Problem Detector*\n---\n\nThe dashboard is used to detect problems with the nodes on which volumes are mounted on by watching the system logs. \nSince npd takes different approach in detecting node problems (parsing system log or dmesg files), it may be hard to find the disk device causing the actual problem. So, this dashboard currently associates the node problem(if any) with all the pvc provisioned on that bad node. \n```\nIf there are no probelm with the node on which the volume is mounted then the problem counter(or metric value) for each of the panels below will be '0'. But if any problem occurs then the counter value( or metric value) is increased by 1 everytime that error occurs in the system logs. Each panel below resembles one specific type of error. \n```\n ",
36 | "mode": "markdown"
37 | },
38 | "pluginVersion": "7.5.5",
39 | "timeFrom": null,
40 | "timeShift": null,
41 | "title": "About the Dashboard",
42 | "type": "text"
43 | },
44 | {
45 | "alert": {
46 | "alertRuleTags": {},
47 | "conditions": [
48 | {
49 | "evaluator": {
50 | "params": [0],
51 | "type": "gt"
52 | },
53 | "operator": {
54 | "type": "and"
55 | },
56 | "query": {
57 | "params": ["A", "5m", "now"]
58 | },
59 | "reducer": {
60 | "params": [],
61 | "type": "avg"
62 | },
63 | "type": "query"
64 | }
65 | ],
66 | "executionErrorState": "alerting",
67 | "for": "5m",
68 | "frequency": "1m",
69 | "handler": 1,
70 | "name": "FilesystemIsReadOnly",
71 | "noDataState": "no_data",
72 | "notifications": []
73 | },
74 | "aliasColors": {},
75 | "bars": false,
76 | "dashLength": 10,
77 | "dashes": false,
78 | "datasource": null,
79 | "fieldConfig": {
80 | "defaults": {},
81 | "overrides": []
82 | },
83 | "fill": 0,
84 | "fillGradient": 0,
85 | "gridPos": {
86 | "h": 9,
87 | "w": 12,
88 | "x": 0,
89 | "y": 7
90 | },
91 | "hiddenSeries": false,
92 | "id": 2,
93 | "legend": {
94 | "alignAsTable": true,
95 | "avg": false,
96 | "current": true,
97 | "max": false,
98 | "min": false,
99 | "show": true,
100 | "total": false,
101 | "values": true
102 | },
103 | "lines": true,
104 | "linewidth": 1,
105 | "nullPointMode": "null",
106 | "options": {
107 | "alertThreshold": true
108 | },
109 | "percentage": false,
110 | "pluginVersion": "7.5.5",
111 | "pointradius": 2,
112 | "points": false,
113 | "renderer": "flot",
114 | "seriesOverrides": [],
115 | "spaceLength": 10,
116 | "stack": false,
117 | "steppedLine": false,
118 | "targets": [
119 | {
120 | "exemplar": true,
121 | "expr": "(kubelet_volume_stats_inodes * 0) + on(node) group_left(reason) problem_counter{reason=\"FilesystemIsReadOnly\"}",
122 | "format": "time_series",
123 | "interval": "",
124 | "legendFormat": "Node: {{ node}}, PVC: {{ persistentvolumeclaim }} ",
125 | "refId": "A"
126 | }
127 | ],
128 | "thresholds": [
129 | {
130 | "colorMode": "critical",
131 | "fill": true,
132 | "line": true,
133 | "op": "gt",
134 | "value": 0,
135 | "visible": true
136 | }
137 | ],
138 | "timeFrom": null,
139 | "timeRegions": [],
140 | "timeShift": null,
141 | "title": "FilesystemIsReadOnly",
142 | "tooltip": {
143 | "shared": true,
144 | "sort": 0,
145 | "value_type": "individual"
146 | },
147 | "type": "graph",
148 | "xaxis": {
149 | "buckets": null,
150 | "mode": "time",
151 | "name": null,
152 | "show": true,
153 | "values": []
154 | },
155 | "yaxes": [
156 | {
157 | "$$hashKey": "object:965",
158 | "format": "short",
159 | "label": null,
160 | "logBase": 1,
161 | "max": null,
162 | "min": null,
163 | "show": true
164 | },
165 | {
166 | "$$hashKey": "object:966",
167 | "format": "short",
168 | "label": null,
169 | "logBase": 1,
170 | "max": null,
171 | "min": null,
172 | "show": false
173 | }
174 | ],
175 | "yaxis": {
176 | "align": false,
177 | "alignLevel": null
178 | }
179 | },
180 | {
181 | "alert": {
182 | "alertRuleTags": {},
183 | "conditions": [
184 | {
185 | "evaluator": {
186 | "params": [0],
187 | "type": "gt"
188 | },
189 | "operator": {
190 | "type": "and"
191 | },
192 | "query": {
193 | "params": ["A", "5m", "now"]
194 | },
195 | "reducer": {
196 | "params": [],
197 | "type": "avg"
198 | },
199 | "type": "query"
200 | }
201 | ],
202 | "executionErrorState": "alerting",
203 | "for": "5m",
204 | "frequency": "1m",
205 | "handler": 1,
206 | "name": "Ext4Error",
207 | "noDataState": "no_data",
208 | "notifications": []
209 | },
210 | "aliasColors": {},
211 | "bars": false,
212 | "dashLength": 10,
213 | "dashes": false,
214 | "datasource": null,
215 | "fieldConfig": {
216 | "defaults": {},
217 | "overrides": []
218 | },
219 | "fill": 1,
220 | "fillGradient": 0,
221 | "gridPos": {
222 | "h": 9,
223 | "w": 12,
224 | "x": 12,
225 | "y": 7
226 | },
227 | "hiddenSeries": false,
228 | "id": 4,
229 | "legend": {
230 | "alignAsTable": true,
231 | "avg": false,
232 | "current": true,
233 | "max": false,
234 | "min": false,
235 | "show": true,
236 | "total": false,
237 | "values": true
238 | },
239 | "lines": true,
240 | "linewidth": 1,
241 | "nullPointMode": "null",
242 | "options": {
243 | "alertThreshold": true
244 | },
245 | "percentage": false,
246 | "pluginVersion": "7.5.5",
247 | "pointradius": 2,
248 | "points": false,
249 | "renderer": "flot",
250 | "seriesOverrides": [],
251 | "spaceLength": 10,
252 | "stack": false,
253 | "steppedLine": false,
254 | "targets": [
255 | {
256 | "exemplar": true,
257 | "expr": "(kubelet_volume_stats_inodes * 0) + on(node) group_left(reason) problem_counter{reason=\"Ext4Error\"}",
258 | "interval": "",
259 | "legendFormat": "Node: {{ node}}, PVC: {{ persistentvolumeclaim }}",
260 | "refId": "A"
261 | }
262 | ],
263 | "thresholds": [
264 | {
265 | "colorMode": "critical",
266 | "fill": true,
267 | "line": true,
268 | "op": "gt",
269 | "value": 0,
270 | "visible": true
271 | }
272 | ],
273 | "timeFrom": null,
274 | "timeRegions": [],
275 | "timeShift": null,
276 | "title": "Ext4Error",
277 | "tooltip": {
278 | "shared": true,
279 | "sort": 0,
280 | "value_type": "individual"
281 | },
282 | "type": "graph",
283 | "xaxis": {
284 | "buckets": null,
285 | "mode": "time",
286 | "name": null,
287 | "show": true,
288 | "values": []
289 | },
290 | "yaxes": [
291 | {
292 | "$$hashKey": "object:1379",
293 | "format": "short",
294 | "label": null,
295 | "logBase": 1,
296 | "max": null,
297 | "min": null,
298 | "show": true
299 | },
300 | {
301 | "$$hashKey": "object:1380",
302 | "format": "short",
303 | "label": null,
304 | "logBase": 1,
305 | "max": null,
306 | "min": null,
307 | "show": false
308 | }
309 | ],
310 | "yaxis": {
311 | "align": false,
312 | "alignLevel": null
313 | }
314 | },
315 | {
316 | "alert": {
317 | "alertRuleTags": {},
318 | "conditions": [
319 | {
320 | "evaluator": {
321 | "params": [0],
322 | "type": "gt"
323 | },
324 | "operator": {
325 | "type": "and"
326 | },
327 | "query": {
328 | "params": ["A", "5m", "now"]
329 | },
330 | "reducer": {
331 | "params": [],
332 | "type": "avg"
333 | },
334 | "type": "query"
335 | }
336 | ],
337 | "executionErrorState": "alerting",
338 | "for": "5m",
339 | "frequency": "1m",
340 | "handler": 1,
341 | "name": "IOError",
342 | "noDataState": "no_data",
343 | "notifications": []
344 | },
345 | "aliasColors": {},
346 | "bars": false,
347 | "dashLength": 10,
348 | "dashes": false,
349 | "datasource": null,
350 | "fieldConfig": {
351 | "defaults": {},
352 | "overrides": []
353 | },
354 | "fill": 1,
355 | "fillGradient": 0,
356 | "gridPos": {
357 | "h": 8,
358 | "w": 12,
359 | "x": 0,
360 | "y": 16
361 | },
362 | "hiddenSeries": false,
363 | "id": 6,
364 | "legend": {
365 | "alignAsTable": true,
366 | "avg": false,
367 | "current": true,
368 | "max": false,
369 | "min": false,
370 | "show": true,
371 | "total": false,
372 | "values": true
373 | },
374 | "lines": true,
375 | "linewidth": 1,
376 | "nullPointMode": "null",
377 | "options": {
378 | "alertThreshold": true
379 | },
380 | "percentage": false,
381 | "pluginVersion": "7.5.5",
382 | "pointradius": 2,
383 | "points": false,
384 | "renderer": "flot",
385 | "seriesOverrides": [],
386 | "spaceLength": 10,
387 | "stack": false,
388 | "steppedLine": false,
389 | "targets": [
390 | {
391 | "exemplar": true,
392 | "expr": "(kubelet_volume_stats_inodes * 0) + on(node) group_left(reason) problem_counter{reason=\"IOError\"} ",
393 | "interval": "",
394 | "legendFormat": "Node: {{ node}}, PVC: {{ persistentvolumeclaim }}",
395 | "refId": "A"
396 | }
397 | ],
398 | "thresholds": [
399 | {
400 | "colorMode": "critical",
401 | "fill": true,
402 | "line": true,
403 | "op": "gt",
404 | "value": 0,
405 | "visible": true
406 | }
407 | ],
408 | "timeFrom": null,
409 | "timeRegions": [],
410 | "timeShift": null,
411 | "title": "IOError",
412 | "tooltip": {
413 | "shared": true,
414 | "sort": 0,
415 | "value_type": "individual"
416 | },
417 | "type": "graph",
418 | "xaxis": {
419 | "buckets": null,
420 | "mode": "time",
421 | "name": null,
422 | "show": true,
423 | "values": []
424 | },
425 | "yaxes": [
426 | {
427 | "$$hashKey": "object:1470",
428 | "format": "short",
429 | "label": null,
430 | "logBase": 1,
431 | "max": null,
432 | "min": null,
433 | "show": true
434 | },
435 | {
436 | "$$hashKey": "object:1471",
437 | "format": "short",
438 | "label": null,
439 | "logBase": 1,
440 | "max": null,
441 | "min": null,
442 | "show": false
443 | }
444 | ],
445 | "yaxis": {
446 | "align": false,
447 | "alignLevel": null
448 | }
449 | },
450 | {
451 | "alert": {
452 | "alertRuleTags": {},
453 | "conditions": [
454 | {
455 | "evaluator": {
456 | "params": [0],
457 | "type": "gt"
458 | },
459 | "operator": {
460 | "type": "and"
461 | },
462 | "query": {
463 | "params": ["A", "5m", "now"]
464 | },
465 | "reducer": {
466 | "params": [],
467 | "type": "avg"
468 | },
469 | "type": "query"
470 | }
471 | ],
472 | "executionErrorState": "alerting",
473 | "for": "5m",
474 | "frequency": "1m",
475 | "handler": 1,
476 | "name": "Ext4Warning",
477 | "noDataState": "no_data",
478 | "notifications": []
479 | },
480 | "aliasColors": {},
481 | "bars": false,
482 | "dashLength": 10,
483 | "dashes": false,
484 | "datasource": null,
485 | "fieldConfig": {
486 | "defaults": {},
487 | "overrides": []
488 | },
489 | "fill": 1,
490 | "fillGradient": 0,
491 | "gridPos": {
492 | "h": 8,
493 | "w": 12,
494 | "x": 12,
495 | "y": 16
496 | },
497 | "hiddenSeries": false,
498 | "id": 8,
499 | "legend": {
500 | "alignAsTable": true,
501 | "avg": false,
502 | "current": true,
503 | "max": false,
504 | "min": false,
505 | "show": true,
506 | "total": false,
507 | "values": true
508 | },
509 | "lines": true,
510 | "linewidth": 1,
511 | "nullPointMode": "null",
512 | "options": {
513 | "alertThreshold": true
514 | },
515 | "percentage": false,
516 | "pluginVersion": "7.5.5",
517 | "pointradius": 2,
518 | "points": false,
519 | "renderer": "flot",
520 | "seriesOverrides": [],
521 | "spaceLength": 10,
522 | "stack": false,
523 | "steppedLine": false,
524 | "targets": [
525 | {
526 | "exemplar": true,
527 | "expr": "(kubelet_volume_stats_inodes * 0) + on(node) group_left(reason) problem_counter{reason=\"Ext4Warning\"} ",
528 | "interval": "",
529 | "legendFormat": "Node: {{ node}}, PVC: {{ persistentvolumeclaim }} ",
530 | "refId": "A"
531 | }
532 | ],
533 | "thresholds": [
534 | {
535 | "colorMode": "critical",
536 | "fill": true,
537 | "line": true,
538 | "op": "gt",
539 | "value": 0,
540 | "visible": true
541 | }
542 | ],
543 | "timeFrom": null,
544 | "timeRegions": [],
545 | "timeShift": null,
546 | "title": "Ext4Warning",
547 | "tooltip": {
548 | "shared": true,
549 | "sort": 0,
550 | "value_type": "individual"
551 | },
552 | "type": "graph",
553 | "xaxis": {
554 | "buckets": null,
555 | "mode": "time",
556 | "name": null,
557 | "show": true,
558 | "values": []
559 | },
560 | "yaxes": [
561 | {
562 | "$$hashKey": "object:1561",
563 | "format": "short",
564 | "label": null,
565 | "logBase": 1,
566 | "max": null,
567 | "min": null,
568 | "show": true
569 | },
570 | {
571 | "$$hashKey": "object:1562",
572 | "format": "short",
573 | "label": null,
574 | "logBase": 1,
575 | "max": null,
576 | "min": null,
577 | "show": false
578 | }
579 | ],
580 | "yaxis": {
581 | "align": false,
582 | "alignLevel": null
583 | }
584 | }
585 | ],
586 | "refresh": false,
587 | "schemaVersion": 27,
588 | "style": "dark",
589 | "tags": ["npd"],
590 | "templating": {
591 | "list": []
592 | },
593 | "time": {
594 | "from": "now-6h",
595 | "to": "now"
596 | },
597 | "timepicker": {},
598 | "timezone": "",
599 | "title": "OpenEBS / Node Volume Problem",
600 | "uid": "4dCJNj6Mz",
601 | "version": 5
602 | }
603 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/jsonnetfile.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dependencies": [],
4 | "legacyImports": true
5 | }
6 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/lib/dashboards.jsonnet:
--------------------------------------------------------------------------------
1 | local mixin = (import '../mixin.libsonnet').grafanaDashboards;
2 |
3 | {
4 | // To generate dashboards json
5 | [name]: mixin[name]
6 | for name in std.objectFields(mixin)
7 | }
8 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/lib/rules.jsonnet:
--------------------------------------------------------------------------------
1 | local rules = (import '../mixin.libsonnet');
2 | local config = import '../config.libsonnet';
3 |
4 | {
5 | // To generate rules json
6 | [if config._config.alertRules[name] then std.asciiLower(name) + '-rules.json']: rules.rules[name]
7 | for name in std.objectFields(config._config.alertRules)
8 | }
9 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/mixin.libsonnet:
--------------------------------------------------------------------------------
1 | local dashboards = (import 'dashboards/dashboards.libsonnet');
2 | local rules = (import 'rules/rules.libsonnet');
3 | local prometheusRules = (import 'rules/prometheus-rules.libsonnet');
4 |
5 | (import 'config.libsonnet') +
6 | {
7 | grafanaDashboards: dashboards($._config).grafanaDashboards,
8 | rules: rules($._config).prometheusRules,
9 | prometheusRules: prometheusRules($._config).prometheusRules,
10 | }
11 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/rules/npd/npd-rules.libsonnet:
--------------------------------------------------------------------------------
1 | // npd alert rules
2 | function(param) {
3 | //local rules = self,
4 | _config+:: param,
5 | prometheusRules+:: {
6 | npd: {
7 | groups+: [
8 | {
9 | name: 'volume-node',
10 | rules: [
11 | {
12 | alert: 'VolumeNodeFileSystemIsReadOnly',
13 | annotations: {
14 | summary: "Volume mount failed for persistent volume claim '{{ $labels.persistentvolumeclaim }}' on node '{{ $labels.node }}' due to read-only file-system",
15 | description: "Persistent Volume's filesystem on node '{{ $labels.node }}' for persistent volume claim '{{ $labels.persistentvolumeclaim }}' has become read-only",
16 | },
17 | expr: 'kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason="FilesystemIsReadOnly"} > 0',
18 | 'for': '5m',
19 | labels: {
20 | severity: 'critical',
21 | },
22 | },
23 | {
24 | alert: 'VolumeNodeExt4Error',
25 | annotations: {
26 | summary: "Node '{{ $labels.node }}' has encountered errors on ext4 file-system on volume having claim '{{ $labels.persistentvolumeclaim }}'",
27 | description: "Persistent Volume's on node '{{ $labels.node }}' persistent volume claim '{{ $labels.persistentvolumeclaim }}' encountering ext4 filesystem error",
28 | },
29 | expr: 'kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason="Ext4Error"} > 0',
30 | 'for': '5m',
31 | labels: {
32 | severity: 'critical',
33 | },
34 | },
35 | {
36 | alert: 'VolumeNodeIOError',
37 | annotations: {
38 | summary: "IO errors encountered on volume having persistent volume claim '{{ $labels.persistentvolumeclaim }}' on node '{{ $labels.node }}'",
39 | description: "Persistent Volume on node '{{ $labels.node }}' for persistent volume claim '{{ $labels.persistentvolumeclaim }}' encountering errors w.r.t buffer I/O ",
40 | },
41 | expr: 'kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason="IOError"} > 0',
42 | 'for': '5m',
43 | labels: {
44 | severity: 'critical',
45 | },
46 | },
47 | {
48 | alert: 'VolumeNodeExt4Warning',
49 | annotations: {
50 | summary: "Node '{{ $labels.node }}' has encountered warning on ext4 file-system on volume having claim '{{ $labels.persistentvolumeclaim }}'",
51 | description: "Persistent Volume on node '{{ $labels.node }}' receiving ext4 filesystem warning for persistent volume claim '{{ $labels.persistentvolumeclaim }}'",
52 | },
53 | expr: 'kubelet_volume_stats_inodes * on(node) group_left(reason) problem_counter{reason="Ext4Warning"} > 0',
54 | 'for': '5m',
55 | labels: {
56 | severity: 'critical',
57 | },
58 | },
59 | ],
60 | },
61 | ],
62 | },
63 | },
64 | }
65 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/rules/openebs/lvmlocalpv-rules.libsonnet:
--------------------------------------------------------------------------------
1 | function(param) {
2 | //local rules = self,
3 | _config+:: param,
4 | prometheusRules+:: {
5 | lvmLocalPV: {
6 | groups+: [
7 | {
8 | name: 'lvm-pool',
9 | rules: [
10 | {
11 | alert: 'LVMVolumeGroupMissingPhysicalVolume',
12 | annotations: {
13 | componentType: 'volume group',
14 | vgName: '{{ $labels.name }}',
15 | summary: "LVM volume group '{{ $labels.name }}' is missing the underlying physical volume.",
16 | description: "LVM volume group '{{ $labels.name }}' on node '{{ $labels.instance }}' is missing {{ $value }} underlying physical volume(s).",
17 | },
18 | expr: 'lvm_vg_missing_pv_count > 0',
19 | 'for': '5m',
20 | labels: {
21 | severity: 'critical',
22 | product: 'openebs',
23 | engine: 'localpv-lvm',
24 | },
25 | },
26 | {
27 | alert: 'LVMVolumeGroupCapacityLow',
28 | annotations: {
29 | componentType: 'volume group',
30 | vgName: '{{ $labels.name }}',
31 | summary: "LVM volume group '{{ $labels.name }}' is running low on capacity. Already {{ $value }}% of total capacity is consumed.",
32 | description: "LVM volume group '{{ $labels.name }}' on node '{{ $labels.instance }}' has {{ with printf \"lvm_vg_free_size_bytes{instance='%s',name='%s'}\" $labels.instance $labels.name | query }} {{ . | first | value }} {{ end }}bytes of space remaining",
33 | },
34 | expr: '((lvm_vg_total_size_bytes - lvm_vg_free_size_bytes)/lvm_vg_total_size_bytes)*100 > 90',
35 | 'for': '5m',
36 | labels: {
37 | severity: 'critical',
38 | product: 'openebs',
39 | engine: 'localpv-lvm',
40 | },
41 | },
42 | {
43 | alert: 'LVMThinPoolCapacityLow',
44 | annotations: {
45 | componentType: 'logical volume',
46 | lvName: '{{ $labels.name }}',
47 | summary: "LVM thin pool '{{ $labels.name }}' is running low on capacity. Already {{ $value }}% of total capacity is consumed.",
48 | description: "LVM thin pool '{{ $labels.name }}' on node '{{ $labels.instance }}' has {{ with printf \"lvm_lv_total_size_bytes{instance='%s',name='%s',segtype='%s'}-((lvm_lv_used_percent{instance='%s',name='%s',segtype='%s'}*lvm_lv_total_size_bytes{instance='%s',name='%s',segtype='%s'})/100)\" $labels.instance $labels.name $labels.segtype $labels.instance $labels.name $labels.segtype $labels.instance $labels.name $labels.segtype | query }} {{ . | first | value }} {{ end }}bytes of space remaining",
49 | },
50 | expr: 'lvm_lv_used_percent{segtype="thin-pool"} > 90',
51 | 'for': '5m',
52 | labels: {
53 | severity: 'critical',
54 | product: 'openebs',
55 | engine: 'localpv-lvm',
56 | },
57 | },
58 | ],
59 | },
60 | ],
61 | },
62 | },
63 | }
64 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/rules/prometheus-rules.libsonnet:
--------------------------------------------------------------------------------
1 | local lvmLocalPV = (import './openebs/lvmlocalpv-rules.libsonnet');
2 | local volume = (import './volume/volume-rules.libsonnet');
3 | local npd = (import './npd/npd-rules.libsonnet');
4 |
5 | // Populate prometheusRules object from volume, and npd rules.
6 | // prometheusRules:{
7 | // groups:[
8 | // {npd alert-1},
9 | // {npd alert-2}
10 | // .
11 | // .
12 | // {npd alert-n},
13 | // ...
14 | // ]
15 | // },
16 |
17 | function(param) {
18 | local prometheusRules = self,
19 | _config+:: param,
20 | prometheusRules+::
21 | lvmLocalPV(prometheusRules._config).prometheusRules.lvmLocalPV + volume(prometheusRules._config).prometheusRules.volume
22 | + npd(prometheusRules._config).prometheusRules.npd,
23 | }
24 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/rules/rules.libsonnet:
--------------------------------------------------------------------------------
1 | local lvmLocalPV = (import './openebs/lvmlocalpv-rules.libsonnet');
2 | local volume = (import './volume/volume-rules.libsonnet');
3 | local npd = (import './npd/npd-rules.libsonnet');
4 |
5 | // Alert rules for different CAS types and others(as defined in config.libsonnet under alertRules) are stored separately in prometheusRules object.
6 | // prometheusRules : {
7 | // mayastor: {
8 | // ...
9 | // },
10 | // ...
11 | // }
12 |
13 | function(param) {
14 | local prometheusRules = self,
15 | _config+:: param,
16 | prometheusRules+::
17 | lvmLocalPV(prometheusRules._config).prometheusRules + volume(prometheusRules._config).prometheusRules
18 | + npd(prometheusRules._config).prometheusRules,
19 | }
20 |
--------------------------------------------------------------------------------
/jsonnet/openebs-mixin/rules/volume/volume-rules.libsonnet:
--------------------------------------------------------------------------------
1 | // alert rules for volume-pvc
2 | function(param) {
3 | //local rules = self,
4 | _config+:: param,
5 | prometheusRules+:: {
6 | volume: {
7 | groups+: [
8 | {
9 | name: 'persistent-volume-claim',
10 | rules: [
11 | {
12 | alert: 'StalePersistentVolumeClaim',
13 | annotations: {
14 | summary: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' in namespace '{{ $labels.namespace }}' is not consumed by any pod in any namespace",
15 | description: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has no consumer",
16 | },
17 | expr: 'kube_persistentvolumeclaim_info unless (kube_persistentvolumeclaim_info * on(persistentvolumeclaim) group_left kube_pod_spec_volumes_persistentvolumeclaims_info) == 1',
18 | 'for': '5m',
19 | labels: {
20 | severity: 'info',
21 | },
22 | },
23 | {
24 | alert: 'PendingPersistentVolumeClaim',
25 | annotations: {
26 | summary: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' pending in namespace '{{ $labels.namespace }}'",
27 | description: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has been in pending state for more than 5 minutes",
28 | },
29 | expr: 'kube_persistentvolumeclaim_status_phase{phase="Pending"} == 1',
30 | 'for': '5m',
31 | labels: {
32 | severity: 'warning',
33 | },
34 | },
35 | {
36 | alert: 'LostPersistentVolumeClaim',
37 | annotations: {
38 | summary: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' in namespace '{{ $labels.namespace }}' lost it's corresponding persistent volume",
39 | description: "Persistent Volume Claim '{{ $labels.persistentvolumeclaim }}' has been in lost state for more than 5 minutes",
40 | },
41 | expr: 'kube_persistentvolumeclaim_status_phase{phase="Lost"} == 1',
42 | 'for': '5m',
43 | labels: {
44 | severity: 'warning',
45 | },
46 | },
47 | ],
48 | },
49 | ],
50 | },
51 | },
52 | }
53 |
--------------------------------------------------------------------------------
/nix/README.md:
--------------------------------------------------------------------------------
1 | ## Overview
2 |
3 | These are a collection of packages we need, or packages where we
4 | want to control the exact version(s) of.
5 |
6 | The packages are imported through the `nix-shell` automatically.
7 |
8 | ## nix-shell
9 |
10 | Build environment including all test and debug dependencies.
11 | It can be run with two arguments:
12 |
13 | * `--arg norust true`: to use your own rust toolchain.
14 | * `--arg devrustup true`: to use rustup.
15 |
--------------------------------------------------------------------------------
/nix/lib/rust.nix:
--------------------------------------------------------------------------------
1 | { sources ? import ../sources.nix }:
2 | let
3 | pkgs =
4 | import sources.nixpkgs { overlays = [ (import sources.rust-overlay) ]; };
5 | makeRustTarget = platform: pkgs.rust.toRustTargetSpec platform;
6 | static_target = makeRustTarget pkgs.pkgsStatic.stdenv.hostPlatform;
7 | in
8 | rec {
9 | inherit makeRustTarget;
10 | rust_default = { override ? { } }: rec {
11 | nightly_pkg = pkgs.rust-bin.nightly."2023-10-05";
12 | stable_pkg = pkgs.rust-bin.stable."1.72.1";
13 |
14 | nightly = nightly_pkg.default.override (override);
15 | stable = stable_pkg.default.override (override);
16 |
17 | nightly_src = nightly_pkg.rust-src;
18 | release_src = stable_pkg.rust-src;
19 | };
20 | default = rust_default { };
21 | default_src = rust_default {
22 | override = { extensions = [ "rust-src" ]; };
23 | };
24 | static = { target ? makeRustTarget pkgs.pkgsStatic.stdenv.hostPlatform }: rust_default {
25 | override = { targets = [ "${target}" ]; };
26 | };
27 | hostStatic = rust_default { override = { targets = [ "${makeRustTarget pkgs.pkgsStatic.stdenv.hostPlatform}" ]; }; };
28 | windows_cross = rust_default {
29 | override = { targets = [ "${pkgs.rust.toRustTargetSpec pkgs.pkgsCross.mingwW64.hostPlatform}" ]; };
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/nix/lib/sourcer.nix:
--------------------------------------------------------------------------------
1 | { lib, stdenv, git, sourcer, tag ? "" }:
2 | let
3 | whitelistSource = src: allowedPrefixes:
4 | builtins.path {
5 | filter = (path: type:
6 | (lib.any
7 | (allowedPrefix:
8 | (lib.hasPrefix (toString (src + "/${allowedPrefix}")) path) ||
9 | (type == "directory" && lib.hasPrefix path (toString (src + "/${allowedPrefix}")))
10 | )
11 | allowedPrefixes)
12 | ## Remove unwanted files, example:
13 | # && path != (toString (src + "/utils/dependencies/scripts/release.sh"))
14 | );
15 | path = src;
16 | name = "puls8";
17 | };
18 | in
19 | {
20 | inherit whitelistSource;
21 |
22 | git-src = whitelistSource ../../. [ ".git" ];
23 | repo-org = whitelistSource ../../mayastor-extensions/dependencies/control-plane/utils/dependencies/scripts [ "git-org-name.sh" ];
24 | }
25 |
--------------------------------------------------------------------------------
/nix/overlay.nix:
--------------------------------------------------------------------------------
1 | {}:
2 | self: super: {
3 | sourcer = super.callPackage ./lib/sourcer.nix { };
4 | }
5 |
--------------------------------------------------------------------------------
/nix/sources.json:
--------------------------------------------------------------------------------
1 | {
2 | "naersk": {
3 | "branch": "master",
4 | "description": "Build rust crates in Nix. No configuration, no code generation, no IFD. Sandbox friendly. [maintainer: @nmattia]",
5 | "homepage": "",
6 | "owner": "nix-community",
7 | "repo": "naersk",
8 | "rev": "d9a33d69a9c421d64c8d925428864e93be895dcc",
9 | "sha256": "1lhz5haibfnbxwir61mhymxfqfgs2q1nb4rk88va8bpv6j2zlpbv",
10 | "type": "tarball",
11 | "url": "https://github.com/nix-community/naersk/archive/d9a33d69a9c421d64c8d925428864e93be895dcc.tar.gz",
12 | "url_template": "https://github.com///archive/.tar.gz"
13 | },
14 | "niv": {
15 | "branch": "master",
16 | "description": "Easy dependency management for Nix projects",
17 | "homepage": "https://github.com/nmattia/niv",
18 | "owner": "nmattia",
19 | "repo": "niv",
20 | "rev": "914aba08a26cb10538b84d00d6cfb01c9776d80c",
21 | "sha256": "0gx316gc7prjay5b0cr13x4zc2pdbiwxkfkpjvrlb2rml80lm4pm",
22 | "type": "tarball",
23 | "url": "https://github.com/nmattia/niv/archive/914aba08a26cb10538b84d00d6cfb01c9776d80c.tar.gz",
24 | "url_template": "https://github.com///archive/.tar.gz"
25 | },
26 | "nixpkgs": {
27 | "branch": "release-22.11",
28 | "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to",
29 | "homepage": "https://github.com/NixOS/nixpkgs",
30 | "owner": "NixOS",
31 | "repo": "nixpkgs",
32 | "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b",
33 | "sha256": "1xi53rlslcprybsvrmipm69ypd3g3hr7wkxvzc73ag8296yclyll",
34 | "type": "tarball",
35 | "url": "https://github.com/NixOS/nixpkgs/archive/ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b.tar.gz",
36 | "url_template": "https://github.com///archive/.tar.gz"
37 | },
38 | "rust-overlay": {
39 | "branch": "master",
40 | "description": "Pure and reproducible nix overlay for binary distributed rust toolchains",
41 | "homepage": "",
42 | "owner": "oxalica",
43 | "repo": "rust-overlay",
44 | "rev": "c0df7f2a856b5ff27a3ce314f6d7aacf5fda546f",
45 | "sha256": "0hm2yznc083bys92h6zrx5lsar5nqphx1h27p7pxz4x7hmilxpsy",
46 | "type": "tarball",
47 | "url": "https://github.com/oxalica/rust-overlay/archive/c0df7f2a856b5ff27a3ce314f6d7aacf5fda546f.tar.gz",
48 | "url_template": "https://github.com///archive/.tar.gz"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/nix/sources.nix:
--------------------------------------------------------------------------------
1 | # This file has been generated by Niv.
2 | let
3 | #
4 | # The fetchers. fetch_ fetches specs of type .
5 | #
6 |
7 | fetch_file = pkgs: spec:
8 | if spec.builtin or true then
9 | builtins_fetchurl { inherit (spec) url sha256; }
10 | else
11 | pkgs.fetchurl { inherit (spec) url sha256; };
12 |
13 | fetch_tarball = pkgs: spec:
14 | if spec.builtin or true then
15 | builtins_fetchTarball { inherit (spec) url sha256; }
16 | else
17 | pkgs.fetchzip { inherit (spec) url sha256; };
18 |
19 | fetch_git = spec:
20 | builtins.fetchGit {
21 | url = spec.repo;
22 | inherit (spec) rev ref;
23 | };
24 |
25 | fetch_builtin-tarball = spec:
26 | builtins.trace ''
27 | WARNING:
28 | The niv type "builtin-tarball" will soon be deprecated. You should
29 | instead use `builtin = true`.
30 |
31 | $ niv modify -a type=tarball -a builtin=true
32 | ''
33 | builtins_fetchTarball
34 | { inherit (spec) url sha256; };
35 |
36 | fetch_builtin-url = spec:
37 | builtins.trace ''
38 | WARNING:
39 | The niv type "builtin-url" will soon be deprecated. You should
40 | instead use `builtin = true`.
41 |
42 | $ niv modify -a type=file -a builtin=true
43 | ''
44 | (builtins_fetchurl { inherit (spec) url sha256; });
45 |
46 | #
47 | # Various helpers
48 | #
49 |
50 | # The set of packages used when specs are fetched using non-builtins.
51 | mkPkgs = sources:
52 | let
53 | sourcesNixpkgs =
54 | import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; })
55 | { };
56 | hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
57 | hasThisAsNixpkgsPath = == ./.;
58 | in
59 | if builtins.hasAttr "nixpkgs" sources then
60 | sourcesNixpkgs
61 | else if hasNixpkgsPath && !hasThisAsNixpkgsPath then
62 | import { }
63 | else
64 | abort ''
65 | Please specify either (through -I or NIX_PATH=nixpkgs=...) or
66 | add a package called "nixpkgs" to your sources.json.
67 | '';
68 |
69 | # The actual fetching function.
70 | fetch = pkgs: name: spec:
71 |
72 | if !builtins.hasAttr "type" spec then
73 | abort "ERROR: niv spec ${name} does not have a 'type' attribute"
74 | else if spec.type == "file" then
75 | fetch_file pkgs spec
76 | else if spec.type == "tarball" then
77 | fetch_tarball pkgs spec
78 | else if spec.type == "git" then
79 | fetch_git spec
80 | else if spec.type == "builtin-tarball" then
81 | fetch_builtin-tarball spec
82 | else if spec.type == "builtin-url" then
83 | fetch_builtin-url spec
84 | else
85 | abort
86 | "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
87 |
88 | # Ports of functions for older nix versions
89 |
90 | # a Nix version of mapAttrs if the built-in doesn't exist
91 | mapAttrs = builtins.mapAttrs or (f: set:
92 | with builtins;
93 | listToAttrs (map
94 | (attr: {
95 | name = attr;
96 | value = f attr set.${attr};
97 | })
98 | (attrNames set)));
99 |
100 | # fetchTarball version that is compatible between all the versions of Nix
101 | builtins_fetchTarball = { url, sha256 }@attrs:
102 | let inherit (builtins) lessThan nixVersion fetchTarball;
103 | in
104 | if lessThan nixVersion "1.12" then
105 | fetchTarball { inherit url; }
106 | else
107 | fetchTarball attrs;
108 |
109 | # fetchurl version that is compatible between all the versions of Nix
110 | builtins_fetchurl = { url, sha256 }@attrs:
111 | let inherit (builtins) lessThan nixVersion fetchurl;
112 | in
113 | if lessThan nixVersion "1.12" then
114 | fetchurl { inherit url; }
115 | else
116 | fetchurl attrs;
117 |
118 | # Create the final "sources" from the config
119 | mkSources = config:
120 | mapAttrs
121 | (name: spec:
122 | if builtins.hasAttr "outPath" spec then
123 | abort
124 | "The values in sources.json should not have an 'outPath' attribute"
125 | else
126 | spec // { outPath = fetch config.pkgs name spec; })
127 | config.sources;
128 |
129 | # The "config" used by the fetchers
130 | mkConfig =
131 | { sourcesFile ? ./sources.json
132 | , sources ? builtins.fromJSON (builtins.readFile sourcesFile)
133 | , pkgs ? mkPkgs sources
134 | }: rec {
135 | # The sources, i.e. the attribute set of spec name to spec
136 | inherit sources;
137 |
138 | # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
139 | inherit pkgs;
140 | };
141 | in
142 | mkSources (mkConfig { }) // {
143 | __functor = _: settings: mkSources (mkConfig settings);
144 | }
145 |
--------------------------------------------------------------------------------
/scripts/generate-readme.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPTDIR=$(dirname "$0")
4 | ROOTDIR="$(realpath $SCRIPTDIR/..)"
5 | CHART_DIR="$ROOTDIR/deploy/charts"
6 | README="README.md"
7 | SKIP_GIT=${SKIP_GIT:-}
8 |
9 | set -euo pipefail
10 |
11 | helm-docs -c "$ROOTDIR" -g "$CHART_DIR" -o $README
12 |
13 |
14 | if [ -z "$SKIP_GIT" ]; then
15 | git diff --exit-code "$CHART_DIR/$README"
16 | fi
17 |
--------------------------------------------------------------------------------
/scripts/shell.nix:
--------------------------------------------------------------------------------
1 | {}:
2 | let
3 | sources = import ../nix/sources.nix;
4 | pkgs = import sources.nixpkgs {
5 | overlays = [ (_: _: { inherit sources; }) (import ../nix/overlay.nix { }) ];
6 | };
7 | in
8 | with pkgs;
9 | let
10 | in
11 | mkShell {
12 | name = "helm-scripts-shell";
13 | buildInputs = [
14 | coreutils
15 | git
16 | helm-docs
17 | kubernetes-helm-wrapped
18 | semver-tool
19 | yq-go
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------