"Fossies" - the Fresh Open Source Software Archive

Member "icinga2-2.10.5/plugins/check_swap.cpp" (23 May 2019, 8201 Bytes) of package /linux/misc/icinga2-2.10.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "check_swap.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.10.2_vs_2.10.3.

    1 /******************************************************************************
    2  * Icinga 2                                                                   *
    3  * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/)      *
    4  *                                                                            *
    5  * This program is free software; you can redistribute it and/or              *
    6  * modify it under the terms of the GNU General Public License                *
    7  * as published by the Free Software Foundation; either version 2             *
    8  * of the License, or (at your option) any later version.                     *
    9  *                                                                            *
   10  * This program is distributed in the hope that it will be useful,            *
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
   13  * GNU General Public License for more details.                               *
   14  *                                                                            *
   15  * You should have received a copy of the GNU General Public License          *
   16  * along with this program; if not, write to the Free Software Foundation     *
   17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
   18  ******************************************************************************/
   19 
   20 #include "plugins/thresholds.hpp"
   21 #include <boost/program_options.hpp>
   22 #include <iostream>
   23 #include <shlwapi.h>
   24 #include <Psapi.h>
   25 #include <vector>
   26 
   27 #define VERSION 1.0
   28 
   29 namespace po = boost::program_options;
   30 
   31 struct printInfoStruct
   32 {
   33     threshold warn;
   34     threshold crit;
   35     double tSwap;
   36     double aSwap;
   37     double percentFree;
   38     Bunit unit = BunitMB;
   39     bool showUsed;
   40 };
   41 
   42 struct pageFileInfo
   43 {
   44     SIZE_T totalSwap;
   45     SIZE_T availableSpwap;
   46 };
   47 
   48 static bool l_Debug;
   49 
   50 BOOL EnumPageFilesProc(LPVOID pContext, PENUM_PAGE_FILE_INFORMATION pPageFileInfo, LPCTSTR lpFilename) {
   51     std::vector<pageFileInfo>* pageFile = static_cast<std::vector<pageFileInfo>*>(pContext);
   52     SYSTEM_INFO systemInfo;
   53 
   54     GetSystemInfo(&systemInfo);
   55 
   56     // pPageFileInfo output is in pages, we need to multiply it by the page size
   57     pageFile->push_back({ pPageFileInfo->TotalSize * systemInfo.dwPageSize, (pPageFileInfo->TotalSize - pPageFileInfo->TotalInUse) * systemInfo.dwPageSize });
   58 
   59     return TRUE;
   60 }
   61 
   62 static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
   63 {
   64     WCHAR namePath[MAX_PATH];
   65     GetModuleFileName(NULL, namePath, MAX_PATH);
   66     WCHAR *progName = PathFindFileName(namePath);
   67 
   68     po::options_description desc;
   69 
   70     desc.add_options()
   71         ("help,h", "Print help message and exit")
   72         ("version,V", "Print version and exit")
   73         ("debug,d", "Verbose/Debug output")
   74         ("warning,w", po::wvalue<std::wstring>(), "Warning threshold")
   75         ("critical,c", po::wvalue<std::wstring>(), "Critical threshold")
   76         ("unit,u", po::wvalue<std::wstring>(), "The unit to use for display (default MB)")
   77         ("show-used,U", "Show used swap instead of the free swap")
   78         ;
   79 
   80     po::wcommand_line_parser parser(ac, av);
   81 
   82     try {
   83         po::store(
   84             parser
   85             .options(desc)
   86             .style(
   87                 po::command_line_style::unix_style |
   88                 po::command_line_style::allow_long_disguise)
   89             .run(),
   90             vm);
   91         vm.notify();
   92     } catch (const std::exception& e) {
   93         std::cout << e.what() << '\n' << desc << '\n';
   94         return 3;
   95     }
   96 
   97     if (vm.count("help")) {
   98         std::wcout << progName << " Help\n\tVersion: " << VERSION << '\n';
   99         wprintf(
  100             L"%s is a simple program to check a machines swap in percent.\n"
  101             L"You can use the following options to define its behaviour:\n\n", progName);
  102         std::cout << desc;
  103         wprintf(
  104             L"\nIt will then output a string looking something like this:\n\n"
  105             L"\tSWAP WARNING - 20%% free | swap=2000B;3000;500;0;10000\n\n"
  106             L"\"SWAP\" being the type of the check, \"WARNING\" the returned status\n"
  107             L"and \"20%%\" is the returned value.\n"
  108             L"The performance data is found behind the \"|\", in order:\n"
  109             L"returned value, warning threshold, critical threshold, minimal value and,\n"
  110             L"if applicable, the maximal value. Performance data will only be displayed when\n"
  111             L"you set at least one threshold\n\n"
  112             L"%s' exit codes denote the following:\n"
  113             L" 0\tOK,\n\tNo Thresholds were broken or the programs check part was not executed\n"
  114             L" 1\tWARNING,\n\tThe warning, but not the critical threshold was broken\n"
  115             L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
  116             L" 3\tUNKNOWN, \n\tThe program experienced an internal or input error\n\n"
  117             L"Threshold syntax:\n\n"
  118             L"-w THRESHOLD\n"
  119             L"warn if threshold is broken, which means VALUE > THRESHOLD\n"
  120             L"(unless stated differently)\n\n"
  121             L"-w !THRESHOLD\n"
  122             L"inverts threshold check, VALUE < THRESHOLD (analogous to above)\n\n"
  123             L"-w [THR1-THR2]\n"
  124             L"warn is VALUE is inside the range spanned by THR1 and THR2\n\n"
  125             L"-w ![THR1-THR2]\n"
  126             L"warn if VALUE is outside the range spanned by THR1 and THR2\n\n"
  127             L"-w THRESHOLD%%\n"
  128             L"if the plugin accepts percentage based thresholds those will be used.\n"
  129             L"Does nothing if the plugin does not accept percentages, or only uses\n"
  130             L"percentage thresholds. Ranges can be used with \"%%\", but both range values need\n"
  131             L"to end with a percentage sign.\n\n"
  132             L"All of these options work with the critical threshold \"-c\" too.\n"
  133             , progName);
  134         std::cout << '\n';
  135         return 0;
  136     }
  137 
  138     if (vm.count("version"))
  139         std::wcout << L"Version: " << VERSION << '\n';
  140 
  141     if (vm.count("warning")) {
  142         try {
  143             printInfo.warn = threshold(vm["warning"].as<std::wstring>());
  144         } catch (const std::invalid_argument& e) {
  145             std::cout << e.what() << '\n';
  146             return 3;
  147         }
  148         printInfo.warn.legal = !printInfo.warn.legal;
  149     }
  150 
  151     if (vm.count("critical")) {
  152         try {
  153             printInfo.crit = threshold(vm["critical"].as<std::wstring>());
  154         } catch (const std::invalid_argument& e) {
  155             std::cout << e.what() << '\n';
  156             return 3;
  157         }
  158         printInfo.crit.legal = !printInfo.crit.legal;
  159     }
  160 
  161     l_Debug = vm.count("debug") > 0;
  162 
  163     if (vm.count("unit")) {
  164         try {
  165             printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>());
  166         } catch (const std::invalid_argument& e) {
  167             std::cout << e.what() << '\n';
  168             return 3;
  169         }
  170     }
  171 
  172     if (vm.count("show-used")) {
  173         printInfo.showUsed = true;
  174         printInfo.warn.legal = true;
  175         printInfo.crit.legal = true;
  176     }
  177 
  178     return -1;
  179 }
  180 
  181 static int printOutput(printInfoStruct& printInfo)
  182 {
  183     if (l_Debug)
  184         std::wcout << L"Constructing output string" << '\n';
  185 
  186     state state = OK;
  187 
  188     std::wcout << L"SWAP ";
  189 
  190     double currentValue;
  191 
  192     if (!printInfo.showUsed)
  193         currentValue = printInfo.aSwap;
  194     else
  195         currentValue = printInfo.tSwap - printInfo.aSwap;
  196 
  197     if (printInfo.warn.rend(currentValue, printInfo.tSwap))
  198         state = WARNING;
  199 
  200     if (printInfo.crit.rend(currentValue, printInfo.tSwap))
  201         state = CRITICAL;
  202 
  203     std::wcout << stateToString(state) << " - ";
  204 
  205     if (!printInfo.showUsed)
  206         std::wcout << printInfo.percentFree << L"% free ";
  207     else
  208         std::wcout << 100 - printInfo.percentFree << L"% used ";
  209 
  210     std::wcout << "| 'swap'=" << currentValue << BunitStr(printInfo.unit) << L";"
  211         << printInfo.warn.pString(printInfo.tSwap) << L";" << printInfo.crit.pString(printInfo.tSwap)
  212         << L";0;" << printInfo.tSwap << '\n';
  213 
  214     return state;
  215 }
  216 
  217 static int check_swap(printInfoStruct& printInfo)
  218 {
  219     PENUM_PAGE_FILE_CALLBACK pageFileCallback = &EnumPageFilesProc;
  220     std::vector<pageFileInfo> pageFiles;
  221 
  222     if(!EnumPageFiles(pageFileCallback, &pageFiles)) {
  223         printErrorInfo();
  224         return 3;
  225     }
  226 
  227     for (int i = 0; i < pageFiles.size(); i++) {
  228         printInfo.tSwap += round(pageFiles.at(i).totalSwap / pow(1024.0, printInfo.unit));
  229         printInfo.aSwap += round(pageFiles.at(i).availableSpwap / pow(1024.0, printInfo.unit));
  230     }
  231 
  232     if (printInfo.aSwap > 0 && printInfo.tSwap > 0)
  233         printInfo.percentFree = 100.0 * printInfo.aSwap / printInfo.tSwap;
  234     else
  235         printInfo.percentFree = 0;
  236 
  237     return -1;
  238 }
  239 
  240 int wmain(int argc, WCHAR **argv)
  241 {
  242     printInfoStruct printInfo = { };
  243     po::variables_map vm;
  244 
  245     int ret = parseArguments(argc, argv, vm, printInfo);
  246     if (ret != -1)
  247         return ret;
  248 
  249     ret = check_swap(printInfo);
  250     if (ret != -1)
  251         return ret;
  252 
  253     return printOutput(printInfo);
  254 }