├── COPYING-GPLV2 ├── COPYING-LGPLV3 ├── README.md ├── docker └── docker-compose.yml ├── etc └── grafana │ └── grafana.ini ├── gmetrics.conf.sample ├── gmetrics.py └── setup └── add_datasource.json /COPYING-GPLV2: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /COPYING-LGPLV3: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Installation Process 2 | 3 | ## Objective: 4 | Run a Grafana instance to provide a monitoring dashboard to a gluster cluster. 5 | 6 | ## Pre-requisites 7 | ### Monitoring host 8 | - docker and docker-compose (for simplicity) 9 | - grafana image (official latest 4.3 release from docker hub) 10 | - graphite image (docker.io/abezhenar/graphite-centos7) 11 | - the storage for the graphite database should be on SSD/flash if possible 12 | 13 | ### GlusterFS cluster machine 14 | - python 15 | - pip install graphitesend 16 | 17 | 18 | ## Installation Sequence 19 | Install the monitoring endpoint first, and then setup the collect points on 20 | each of the Gluster nodes. 21 | 22 | 23 | ## Setting Up the monitoring endpoint 24 | On the monitoring host, perform the following steps; 25 | 1. Pull the required docker images (*listed above*) 26 | 2. we need to persist the grafana configuration db and settings, as well as the 27 | graphite data. 28 | ```markdown 29 | mkdir -p /opt/docker/grafana/etc 30 | mkdir -p /opt/docker/grafana/data/plugins 31 | mkdir -p /opt/docker/graphite 32 | ``` 33 | 3. Download the additional status panel plugin 34 | ```markdown 35 | cd /opt/docker/grafana/data/plugins 36 | wget https://grafana.com/api/plugins/vonage-status-panel/versions/1.0.4/download 37 | unzip download 38 | rm -f download 39 | ``` 40 | 4. Copy the seed .ini file for grafana to the containers etc directory, and reset 41 | the permissions to be compatible with the containers 42 | ```markdown 43 | cp etc/grafana/grafana.ini /opt/docker/grafana/etc 44 | chown -R 104:107 /opt/docker/grafana 45 | chown -R 997 /opt/docker/graphite 46 | chmod g+w /opt/docker/graphite 47 | 48 | ``` 49 | 5. Edit the `docker/docker-compose.yml` example (if necessary) 50 | 6. Run docker compose 51 | ``` 52 | cd docker/ 53 | docker-compose up -d 54 | ``` 55 | 7. check that the containers are running and the endpoints are listening 56 | 7.1 Use ```docker ps``` 57 | 7.2 use ```netstat``` and look for the following ports: 3000,80,2003,2004,7002 58 | 59 | 8. Add the graphite instance as a datasource to grafana 60 | 8.1 register the graphite instance to grafana as the default data source 61 | ```markdown 62 | curl -u admin:admin -H "Content-Type: application/json" -X POST http://localhost:3000/api/datasources \ 63 | --data-binary @setup/add_datasource.json 64 | ``` 65 | 66 | ## Configuration on Each Gluster Node 67 | * You may need to update your SELINUX policy to allow the write_graphite plugin 68 | to access outbound on port 2003. To test, simply disable SELINUX 69 | * Install Gluster metrics library to enable tracking utilization, process and 70 | diskstats 71 | 72 | sudo pip install git+https://github.com/gluster/glustercli-python.git 73 | 74 | * Run below command to start sending metrics to graphite server 75 | 76 | ``` 77 | $ python gmetrics.py 78 | ``` 79 | 80 | Graphite server and hostname can be configured using, 81 | 82 | ``` 83 | $ python gmetrics.py --graphite-server localhost --hostname local 84 | ``` 85 | 86 | ## Configurations 87 | To customize the gmetrics, create a config file and override the settings 88 | 89 | [settings] 90 | interval=10 91 | enabled_metrics=local_io,local_process 92 | prefix=gbench_testing 93 | group=perf_test_1 94 | 95 | And call `gmetrics.py` using, 96 | 97 | ``` 98 | $ python gmetrics.py -c /root/gmetrics.conf --graphite-server localhost \ 99 | --hostname local 100 | ``` 101 | 102 | Configuration change will be detected automatically by `gmetrics.py`, config 103 | file can be edited as required. 104 | 105 | Available options for `enabled_metrics` are 106 | 107 | ``` 108 | "local_io", 109 | "local_utilization", 110 | "local_diskstats", 111 | "local_process" 112 | ``` 113 | 114 | ## Known Issues 115 | * After login to grafana, currently users have to setup the dashboard themself. 116 | * (**TODO**) Update other known issues 117 | 118 | 119 | ## Credits 120 | 121 | Setting up of docker images for graphite and grafana section in this README is taken over from [cephmetrics](https://github.com/ceph/cephmetrics). 122 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | grafana: 5 | image: docker.io/grafana/grafana:latest 6 | container_name: grafana 7 | network_mode: "host" 8 | ports: 9 | - "3000:3000" 10 | volumes: 11 | - /opt/docker/grafana/data:/var/lib/grafana:Z 12 | - /opt/docker/grafana/etc:/etc/grafana:Z 13 | depends_on: 14 | - graphite 15 | graphite: 16 | image: docker.io/abezhenar/graphite-centos7 17 | container_name: graphite 18 | network_mode: "host" 19 | ports: 20 | - "80:80" 21 | - "2003:2003" 22 | - "2004:2004" 23 | - "7002:7002" 24 | volumes: 25 | - /opt/docker/graphite:/var/lib/graphite/storage/whisper:Z 26 | -------------------------------------------------------------------------------- /etc/grafana/grafana.ini: -------------------------------------------------------------------------------- 1 | ##################### Grafana Configuration Example ##################### 2 | # 3 | # Everything has defaults so you only need to uncomment things you want to 4 | # change 5 | 6 | # possible values : production, development 7 | ; app_mode = production 8 | 9 | # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty 10 | ; instance_name = ${HOSTNAME} 11 | 12 | #################################### Paths #################################### 13 | [paths] 14 | # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) 15 | # 16 | ;data = /var/lib/grafana 17 | # 18 | # Directory where grafana can store logs 19 | # 20 | ;logs = /var/log/grafana 21 | # 22 | # Directory where grafana will automatically scan and look for plugins 23 | # 24 | ;plugins = /var/lib/grafana/plugins 25 | 26 | # 27 | #################################### Server #################################### 28 | [server] 29 | # Protocol (http, https, socket) 30 | ;protocol = http 31 | 32 | # The ip address to bind to, empty will bind to all interfaces 33 | ;http_addr = 34 | 35 | # The http port to use 36 | ;http_port = 3000 37 | 38 | # The public facing domain name used to access grafana from a browser 39 | ;domain = localhost 40 | 41 | # Redirect to correct domain if host header does not match domain 42 | # Prevents DNS rebinding attacks 43 | ;enforce_domain = false 44 | 45 | # The full public facing url you use in browser, used for redirects and emails 46 | # If you use reverse proxy and sub path specify full url (with sub path) 47 | ;root_url = http://localhost:3000 48 | 49 | # Log web requests 50 | ;router_logging = false 51 | 52 | # the path relative working path 53 | ;static_root_path = public 54 | 55 | # enable gzip 56 | ;enable_gzip = false 57 | 58 | # https certs & key file 59 | ;cert_file = 60 | ;cert_key = 61 | 62 | # Unix socket path 63 | ;socket = 64 | 65 | #################################### Database #################################### 66 | [database] 67 | # You can configure the database connection by specifying type, host, name, user and password 68 | # as seperate properties or as on string using the url propertie. 69 | 70 | # Either "mysql", "postgres" or "sqlite3", it's your choice 71 | ;type = sqlite3 72 | ;host = 127.0.0.1:3306 73 | ;name = grafana 74 | ;user = root 75 | # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;""" 76 | ;password = 77 | 78 | # Use either URL or the previous fields to configure the database 79 | # Example: mysql://user:secret@host:port/database 80 | ;url = 81 | 82 | # For "postgres" only, either "disable", "require" or "verify-full" 83 | ;ssl_mode = disable 84 | 85 | # For "sqlite3" only, path relative to data_path setting 86 | ;path = grafana.db 87 | 88 | # Max conn setting default is 0 (mean not set) 89 | ;max_idle_conn = 90 | ;max_open_conn = 91 | 92 | 93 | #################################### Session #################################### 94 | [session] 95 | # Either "memory", "file", "redis", "mysql", "postgres", default is "file" 96 | ;provider = file 97 | 98 | # Provider config options 99 | # memory: not have any config yet 100 | # file: session dir path, is relative to grafana data_path 101 | # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` 102 | # mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name` 103 | # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable 104 | ;provider_config = sessions 105 | 106 | # Session cookie name 107 | ;cookie_name = grafana_sess 108 | 109 | # If you use session in https only, default is false 110 | ;cookie_secure = false 111 | 112 | # Session life time, default is 86400 113 | ;session_life_time = 86400 114 | 115 | #################################### Data proxy ########################### 116 | [dataproxy] 117 | 118 | # This enables data proxy logging, default is false 119 | ;logging = false 120 | 121 | 122 | #################################### Analytics #################################### 123 | [analytics] 124 | # Server reporting, sends usage counters to stats.grafana.org every 24 hours. 125 | # No ip addresses are being tracked, only simple counters to track 126 | # running instances, dashboard and error counts. It is very helpful to us. 127 | # Change this option to false to disable reporting. 128 | ;reporting_enabled = true 129 | 130 | # Set to false to disable all checks to https://grafana.net 131 | # for new vesions (grafana itself and plugins), check is used 132 | # in some UI views to notify that grafana or plugin update exists 133 | # This option does not cause any auto updates, nor send any information 134 | # only a GET request to http://grafana.com to get latest versions 135 | ;check_for_updates = true 136 | 137 | # Google Analytics universal tracking code, only enabled if you specify an id here 138 | ;google_analytics_ua_id = 139 | 140 | #################################### Security #################################### 141 | [security] 142 | # default admin user, created on startup 143 | ;admin_user = admin 144 | 145 | # default admin password, can be changed before first start of grafana, or in profile settings 146 | ;admin_password = admin 147 | 148 | # used for signing 149 | ;secret_key = SW2YcwTIb9zpOOhoPsMm 150 | 151 | # Auto-login remember days 152 | ;login_remember_days = 7 153 | ;cookie_username = grafana_user 154 | ;cookie_remember_name = grafana_remember 155 | 156 | # disable gravatar profile images 157 | ;disable_gravatar = false 158 | 159 | # data source proxy whitelist (ip_or_domain:port separated by spaces) 160 | ;data_source_proxy_whitelist = 161 | 162 | [snapshots] 163 | # snapshot sharing options 164 | ;external_enabled = true 165 | ;external_snapshot_url = https://snapshots-origin.raintank.io 166 | ;external_snapshot_name = Publish to snapshot.raintank.io 167 | 168 | # remove expired snapshot 169 | ;snapshot_remove_expired = true 170 | 171 | # remove snapshots after 90 days 172 | ;snapshot_TTL_days = 90 173 | 174 | #################################### Users #################################### 175 | [users] 176 | # disable user signup / registration 177 | ;allow_sign_up = true 178 | 179 | # Allow non admin users to create organizations 180 | ;allow_org_create = true 181 | 182 | # Set to true to automatically assign new users to the default organization (id 1) 183 | ;auto_assign_org = true 184 | 185 | # Default role new users will be automatically assigned (if disabled above is set to true) 186 | ;auto_assign_org_role = Viewer 187 | 188 | # Background text for the user field on the login page 189 | ;login_hint = email or username 190 | 191 | # Default UI theme ("dark" or "light") 192 | ;default_theme = dark 193 | 194 | [auth] 195 | # Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false 196 | ;disable_login_form = false 197 | 198 | # Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false 199 | ;disable_signout_menu = false 200 | 201 | #################################### Anonymous Auth ########################## 202 | [auth.anonymous] 203 | # enable anonymous access 204 | ;enabled = false 205 | 206 | # specify organization name that should be used for unauthenticated users 207 | ;org_name = Main Org. 208 | 209 | # specify role for unauthenticated users 210 | ;org_role = Viewer 211 | 212 | #################################### Github Auth ########################## 213 | [auth.github] 214 | ;enabled = false 215 | ;allow_sign_up = true 216 | ;client_id = some_id 217 | ;client_secret = some_secret 218 | ;scopes = user:email,read:org 219 | ;auth_url = https://github.com/login/oauth/authorize 220 | ;token_url = https://github.com/login/oauth/access_token 221 | ;api_url = https://api.github.com/user 222 | ;team_ids = 223 | ;allowed_organizations = 224 | 225 | #################################### Google Auth ########################## 226 | [auth.google] 227 | ;enabled = false 228 | ;allow_sign_up = true 229 | ;client_id = some_client_id 230 | ;client_secret = some_client_secret 231 | ;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email 232 | ;auth_url = https://accounts.google.com/o/oauth2/auth 233 | ;token_url = https://accounts.google.com/o/oauth2/token 234 | ;api_url = https://www.googleapis.com/oauth2/v1/userinfo 235 | ;allowed_domains = 236 | 237 | #################################### Generic OAuth ########################## 238 | [auth.generic_oauth] 239 | ;enabled = false 240 | ;name = OAuth 241 | ;allow_sign_up = true 242 | ;client_id = some_id 243 | ;client_secret = some_secret 244 | ;scopes = user:email,read:org 245 | ;auth_url = https://foo.bar/login/oauth/authorize 246 | ;token_url = https://foo.bar/login/oauth/access_token 247 | ;api_url = https://foo.bar/user 248 | ;team_ids = 249 | ;allowed_organizations = 250 | 251 | #################################### Grafana.com Auth #################### 252 | [auth.grafananet] 253 | ;enabled = false 254 | ;allow_sign_up = true 255 | ;client_id = some_id 256 | ;client_secret = some_secret 257 | ;scopes = user:email 258 | ;allowed_organizations = 259 | 260 | #################################### Auth Proxy ########################## 261 | [auth.proxy] 262 | ;enabled = false 263 | ;header_name = X-WEBAUTH-USER 264 | ;header_property = username 265 | ;auto_sign_up = true 266 | ;ldap_sync_ttl = 60 267 | ;whitelist = 192.168.1.1, 192.168.2.1 268 | 269 | #################################### Basic Auth ########################## 270 | [auth.basic] 271 | ;enabled = true 272 | 273 | #################################### Auth LDAP ########################## 274 | [auth.ldap] 275 | ;enabled = false 276 | ;config_file = /etc/grafana/ldap.toml 277 | ;allow_sign_up = true 278 | 279 | #################################### SMTP / Emailing ########################## 280 | [smtp] 281 | ;enabled = false 282 | ;host = localhost:25 283 | ;user = 284 | # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;""" 285 | ;password = 286 | ;cert_file = 287 | ;key_file = 288 | ;skip_verify = false 289 | ;from_address = admin@grafana.localhost 290 | ;from_name = Grafana 291 | 292 | [emails] 293 | ;welcome_email_on_sign_up = false 294 | 295 | #################################### Logging ########################## 296 | [log] 297 | # Either "console", "file", "syslog". Default is console and file 298 | # Use space to separate multiple modes, e.g. "console file" 299 | ;mode = console file 300 | 301 | # Either "trace", "debug", "info", "warn", "error", "critical", default is "info" 302 | ;level = info 303 | 304 | # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug 305 | ;filters = 306 | 307 | 308 | # For "console" mode only 309 | [log.console] 310 | ;level = 311 | 312 | # log line format, valid options are text, console and json 313 | ;format = console 314 | 315 | # For "file" mode only 316 | [log.file] 317 | ;level = 318 | 319 | # log line format, valid options are text, console and json 320 | ;format = text 321 | 322 | # This enables automated log rotate(switch of following options), default is true 323 | ;log_rotate = true 324 | 325 | # Max line number of single file, default is 1000000 326 | ;max_lines = 1000000 327 | 328 | # Max size shift of single file, default is 28 means 1 << 28, 256MB 329 | ;max_size_shift = 28 330 | 331 | # Segment log daily, default is true 332 | ;daily_rotate = true 333 | 334 | # Expired days of log file(delete after max days), default is 7 335 | ;max_days = 7 336 | 337 | [log.syslog] 338 | ;level = 339 | 340 | # log line format, valid options are text, console and json 341 | ;format = text 342 | 343 | # Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used. 344 | ;network = 345 | ;address = 346 | 347 | # Syslog facility. user, daemon and local0 through local7 are valid. 348 | ;facility = 349 | 350 | # Syslog tag. By default, the process' argv[0] is used. 351 | ;tag = 352 | 353 | 354 | #################################### AMQP Event Publisher ########################## 355 | [event_publisher] 356 | ;enabled = false 357 | ;rabbitmq_url = amqp://localhost/ 358 | ;exchange = grafana_events 359 | 360 | ;#################################### Dashboard JSON files ########################## 361 | [dashboards.json] 362 | ;enabled = false 363 | ;path = /var/lib/grafana/dashboards 364 | 365 | #################################### Alerting ############################ 366 | [alerting] 367 | # Disable alerting engine & UI features 368 | ;enabled = true 369 | # Makes it possible to turn off alert rule execution but alerting UI is visible 370 | ;execute_alerts = true 371 | 372 | #################################### Internal Grafana Metrics ########################## 373 | # Metrics available at HTTP API Url /api/metrics 374 | [metrics] 375 | # Disable / Enable internal metrics 376 | ;enabled = true 377 | 378 | # Publish interval 379 | ;interval_seconds = 10 380 | 381 | # Send internal metrics to Graphite 382 | [metrics.graphite] 383 | # Enable by setting the address setting (ex localhost:2003) 384 | ;address = 385 | ;prefix = prod.grafana.%(instance_name)s. 386 | 387 | #################################### Grafana.com integration ########################## 388 | # Url used to to import dashboards directly from Grafana.com 389 | [grafana_net] 390 | ;url = https://grafana.com 391 | 392 | #################################### External image storage ########################## 393 | [external_image_storage] 394 | # Used for uploading images to public servers so they can be included in slack/email messages. 395 | # you can choose between (s3, webdav) 396 | ;provider = 397 | 398 | [external_image_storage.s3] 399 | ;bucket_url = 400 | ;access_key = 401 | ;secret_key = 402 | 403 | [external_image_storage.webdav] 404 | ;url = 405 | ;public_url = 406 | ;username = 407 | ;password = 408 | -------------------------------------------------------------------------------- /gmetrics.conf.sample: -------------------------------------------------------------------------------- 1 | [settings] 2 | interval=10 3 | enabled_metrics=local_io,local_process,local_utilization,local_diskstats 4 | prefix=glusterfs-perf 5 | group=nightly 6 | -------------------------------------------------------------------------------- /gmetrics.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2017 Red Hat, Inc. 5 | # This file is part of GlusterFS. 6 | # 7 | # This file is licensed to you under your choice of the GNU Lesser 8 | # General Public License, version 3 or any later version (LGPLv3 or 9 | # later), or the GNU General Public License, version 2 (GPLv2), in all 10 | # cases as published by the Free Software Foundation. 11 | 12 | import os, errno, socket 13 | import glob 14 | import time 15 | from ConfigParser import ConfigParser 16 | from argparse import ArgumentParser 17 | import sys 18 | 19 | import graphitesend 20 | 21 | 22 | PLUGIN_NAME = 'glusterfs' 23 | METRICS_DIR = '/var/run/gluster/metrics/' 24 | 25 | # Available metrics and respective metrics collection functions 26 | AVAILABLE_METRICS = [ 27 | "local_io", 28 | "local_utilization", 29 | "local_diskstats", 30 | "local_process", 31 | ] 32 | 33 | metric_keys_diskstats = [ 34 | "reads_completed", 35 | "reads_merged", 36 | "sectors_read", 37 | "time_spent_reading", 38 | "writes_completed", 39 | "writes_merged", 40 | "sectors_written", 41 | "time_spent_writing", 42 | "ios_currently_in_progress", 43 | "time_spent_doing_ios", 44 | "weighted_time_spent_doing_ios" 45 | ] 46 | 47 | metric_keys_utilization = [ 48 | "block_size", 49 | "blocks_total", 50 | "blocks_free", 51 | "blocks_avail", 52 | "inodes_total", 53 | "inodes_free", 54 | "inodes_avail" 55 | ] 56 | 57 | metric_keys_processes = [ 58 | "percentage_cpu", 59 | "percentage_memory", 60 | "resident_memory", 61 | "virtual_memory", 62 | "elapsed_time_sec", 63 | ] 64 | 65 | 66 | def to_strlist(value): 67 | value = value.strip() 68 | if value == "": 69 | return [] 70 | 71 | value = value.split(",") 72 | return [v.strip() for v in value] 73 | 74 | 75 | def to_int(value): 76 | return int(value) 77 | 78 | 79 | # Typecast to desired type after reading from conf file 80 | TYPECAST_MAP = { 81 | "enabled_metrics": to_strlist, 82 | "interval": to_int 83 | } 84 | 85 | # Section name in Conf file 86 | CONF_SECT = "settings" 87 | 88 | # Global GraphiteSend object 89 | g = None 90 | 91 | # Default Config when config file is not passed 92 | DEFAULT_CONFIG = { 93 | "interval": 15, 94 | "enabled_metrics": AVAILABLE_METRICS, 95 | } 96 | 97 | 98 | class Config(object): 99 | def __init__(self, config_file=None): 100 | self.config_file = config_file 101 | self.conf = None 102 | self.load() 103 | self.prev_mtime = None 104 | 105 | def get(self, name, default_value=None): 106 | if self.config_file is None: 107 | return DEFAULT_CONFIG.get(name, default_value) 108 | 109 | if self.conf is None: 110 | return default_value 111 | 112 | if self.conf.has_option(CONF_SECT, name): 113 | val = self.conf.get(CONF_SECT, name) 114 | typecast_func = TYPECAST_MAP.get(name, None) 115 | if typecast_func is not None: 116 | return typecast_func(val) 117 | 118 | return val 119 | else: 120 | return default_value 121 | 122 | def load(self): 123 | if self.config_file is None: 124 | return 125 | 126 | self.conf = ConfigParser() 127 | with open(self.config_file) as f: 128 | self.conf.readfp(f) 129 | 130 | # Store mtime of conf file for future comparison 131 | self.prev_mtime = os.lstat(self.config_file).st_mtime 132 | 133 | def reload(self): 134 | if self.config_file is None: 135 | return False 136 | 137 | st_mtime = os.lstat(self.config_file).st_mtime 138 | if self.prev_mtime is None or st_mtime > self.prev_mtime: 139 | self.load() 140 | return True 141 | 142 | return False 143 | 144 | 145 | def local_io_metrics(): 146 | global g 147 | print "Send Signal to GlusterFS..." 148 | 149 | os.system ("pgrep glusterfs | xargs kill -USR2") 150 | 151 | # Idea is to provide a second for application to dump metrics 152 | time.sleep(1) 153 | 154 | timestamp = time.time() 155 | 156 | for gfile in glob.glob("%s/gmetrics.*" % METRICS_DIR): 157 | with open(gfile) as f: 158 | proc_id = "(null)" 159 | for line in f: 160 | # Handle comments 161 | if "# glusterd" in line: 162 | break 163 | 164 | if "### BrickName: " in line: 165 | proc_id = line.split(":")[1].strip() 166 | continue 167 | 168 | if "(null)" == proc_id and "### MountName: " in line: 169 | proc_id = line.split(":")[1].strip() 170 | continue 171 | 172 | if "#" == line[0]: 173 | continue 174 | 175 | data = line.split(" ") 176 | if len(data) < 2: 177 | break 178 | 179 | # Send all data in single timestamp for better monitoring 180 | key = ".io.%s.%s" % (proc_id, data[0]) 181 | value = data[1].strip() 182 | g.send(key, value, timestamp) 183 | 184 | # Remove the file, so there won't be a repeat 185 | os.remove(gfile) 186 | #print("%s [DONE] " % gfile) 187 | 188 | def local_diskstats_metrics(): 189 | # Local import, only if required 190 | from gluster.metrics import local_diskstats 191 | 192 | global g 193 | 194 | timestamp = time.time() 195 | for data in local_diskstats(): 196 | key_pfx = ".diskstats.{volume}.{node_id}.{brick}.".format(**data) 197 | 198 | for k in metric_keys_diskstats: 199 | g.send(key_pfx + k, data[k], timestamp) 200 | 201 | 202 | def local_utilization_metrics(): 203 | # Local import, only if required 204 | from gluster.metrics import local_utilization 205 | 206 | global g 207 | 208 | timestamp = time.time() 209 | for data in local_utilization(): 210 | key_pfx = ".utilization.{volume}.{node_id}.{brick}.".format(**data) 211 | 212 | for k in metric_keys_utilization: 213 | g.send(key_pfx + k, data[k], timestamp) 214 | 215 | 216 | def local_process_metrics(): 217 | # Local import, only if this metric enabled 218 | from gluster.metrics import local_processes 219 | 220 | global g 221 | 222 | timestamp = time.time() 223 | for data in local_processes(): 224 | if data.get("name", "") == "glusterd": 225 | key_pfx = ".ps.{node_id}.glusterd.".format(**data) 226 | elif data.get("name", "") == "glusterfsd": 227 | key_pfx = (".ps.{volname}.{node_id}.{brick_path}." 228 | "glusterfsd.".format(**data)) 229 | else: 230 | # Not yet implemented tracking for other gluster processes 231 | continue 232 | 233 | for k in metric_keys_processes: 234 | g.send(key_pfx + k, data[k], timestamp) 235 | 236 | 237 | def main(): 238 | global g 239 | 240 | # Arguments Handling 241 | parser = ArgumentParser(description=__doc__) 242 | parser.add_argument("-c", "--config-file", help="Config File") 243 | parser.add_argument("--graphite-server", 244 | help="Graphite Server", 245 | default="localhost") 246 | parser.add_argument("--hostname", 247 | help="Hostname") 248 | args = parser.parse_args() 249 | if not args.hostname: 250 | args.hostname = socket.gethostname() 251 | 252 | # Initialize Graphite Server 253 | g = graphitesend.init(graphite_server=args.graphite_server, 254 | prefix="gmetrics", 255 | system_name=args.hostname, 256 | group="gluster", 257 | fqdn_squash=True) 258 | 259 | # Load Config File 260 | conf = Config(args.config_file) 261 | 262 | enabled_metrics = conf.get("enabled_metrics") 263 | # If enabled_metrics list is empty enable all metrics 264 | if not enabled_metrics: 265 | enabled_metrics = AVAILABLE_METRICS 266 | 267 | # Create the metrics dir in which all the metrics would be dumped 268 | try: 269 | os.mkdir(METRICS_DIR) 270 | except OSError as e: 271 | if e.errno != errno.EEXIST: 272 | raise 273 | 274 | # Metrics collection Loop 275 | while True: 276 | # Reloads only if config file is modified 277 | if conf.reload(): 278 | print "Reloaded Config file" 279 | 280 | # Update the graphitesend prefix/group 281 | prefix_list = [] 282 | prefix_list.append(conf.get("prefix", "gmetrics")) 283 | prefix_list.append(args.hostname) 284 | prefix_list.append(conf.get("group", "gluster")) 285 | 286 | g.formatter.prefix = '.'.join(prefix_list) 287 | 288 | # If Config is reloaded, get enabled metrics list again 289 | enabled_metrics = conf.get("enabled_metrics") 290 | # If enabled_metrics list is empty enable all metrics 291 | if not enabled_metrics: 292 | enabled_metrics = AVAILABLE_METRICS 293 | 294 | # TODO: Not yet Parallel to collect different metrics 295 | for m in enabled_metrics: 296 | metrics_func = globals().get(m + "_metrics", None) 297 | if metrics_func is not None: 298 | print "Sending %s metrics to Graphite" % m 299 | metrics_func() 300 | 301 | # Sleep till next collection interval 302 | time.sleep(conf.get("interval", 15)) 303 | 304 | 305 | if __name__ == "__main__": 306 | try: 307 | main() 308 | except KeyboardInterrupt: 309 | print "Exiting.." 310 | sys.exit(1) 311 | -------------------------------------------------------------------------------- /setup/add_datasource.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"Local", 3 | "type":"graphite", 4 | "url":"http://localhost", 5 | "access":"proxy", 6 | "basicAuth":false, 7 | "isDefault":true 8 | } 9 | --------------------------------------------------------------------------------