In January 2021 we will introduce a 10 GB quota for project repositories. Higher limits for individual projects will be available on request. Please see https://doku.lrz.de/display/PUBLIC/GitLab for more information.

dcdbquery.cpp 5.37 KB
Newer Older
Axel Auweter's avatar
Axel Auweter committed
1 2
//================================================================================
// Name        : dcdbquery.cpp
3
// Author      : Axel Auweter, Daniele Tafani
Micha Müller's avatar
Micha Müller committed
4
// Contact     : info@dcdb.it
Axel Auweter's avatar
Axel Auweter committed
5 6 7 8 9 10
// Copyright   : Leibniz Supercomputing Centre
// Description : Main file of the dcdbquery command line utility
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
11
// Copyright (C) 2011-2019 Leibniz Supercomputing Centre
Axel Auweter's avatar
Axel Auweter committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//================================================================================
27

Axel Auweter's avatar
Axel Auweter committed
28
/* C++ standard headers */
29
#include <iostream>
Axel Auweter's avatar
Axel Auweter committed
30
#include <stdexcept>
31

Axel Auweter's avatar
Axel Auweter committed
32 33
/* C standard headers */
#include <cstdlib>
34
#include <cstring>
Axel Auweter's avatar
Axel Auweter committed
35 36 37 38
#include <unistd.h>

/* Custom headers */
#include "dcdb/timestamp.h"
39
#include "dcdb/version.h"
40
#include "version.h"
Axel Auweter's avatar
Axel Auweter committed
41 42 43 44
#include "query.h"

void usage(void)
{
45 46
  if (isatty(fileno(stdin))) {
      /*            0---------1---------2---------3---------4---------5---------6---------7--------- */
47 48 49 50 51 52 53 54 55 56 57 58
      std::cout << "Usage:" << std::endl;
      std::cout << "  dcdbquery [-h <host>] [-d] [-r] [-l] <Sensor 1> [<Sensor 2> ...] <Start> <End>" << std::endl;
      std::cout << std::endl;
      std::cout << "Parameters:" << std::endl;
      std::cout << "  <Sensor n>    a sensor name" << std::endl;
      std::cout << "  <Start>       start of time series" << std::endl;
      std::cout << "  <End>         end of time series" << std::endl;
      std::cout << std::endl;
      std::cout << "Options:" << std::endl;
      std::cout << "  -h<host>      Cassandra host                         [default: " << DEFAULT_CASSANDRAHOST << ":" << DEFAULT_CASSANDRAPORT << "]" << endl;
      std::cout << "  -r            Report timestamps in numerical format" << std::endl;
      std::cout << "  -l            Report times in local time (not UTC)" << std::endl;
59 60 61 62
  }
  else {
      std::cout << "Invalid request." << std::endl;
  }
Axel Auweter's avatar
Axel Auweter committed
63 64 65
  exit(EXIT_SUCCESS);
}

66
int main(int argc, char * const argv[])
67
{
68 69
  std::cout << "dcdbquery " << VERSION << " (libdcdb " << DCDB::Version::getVersion() << ")" << std::endl << std::endl;

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  /* Check if run from command line */
  int argcReal;
  char **argvReal;
  if (isatty(fileno(stdin))) {
      argcReal = argc;
      argvReal = (char**)argv;
  }
  else {
      /* Check if we are a CGI program */
      if (!getenv("QUERY_STRING")) {
          std::cout << "No terminal and no QUERY_STRING environment variable." << std::endl;
          std::cout << "Exiting." << std::endl;
          exit(EXIT_FAILURE);
      }

85
      /* Print content type */
86
      std::cout << "Content-type: text/plain" << std::endl << std::endl;
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
      /* Create argcReal and argvReal */
      argcReal = 1;
      argvReal = (char**)malloc(sizeof(char*));
      argvReal[0] = strdup("dcdbquery"); /* dummy to make consistent with command line invocation */

      char *token = strtok(getenv("QUERY_STRING"), "&");
      while (token) {
          argcReal++;
          argvReal = (char**)realloc((void*)argvReal, argcReal*sizeof(char*));
          /* FIXME: should check if argvReal is NULL */
          argvReal[argcReal-1] = token;
          token = strtok(NULL, "&");
      }
  }

Axel Auweter's avatar
Axel Auweter committed
103
  /* Check command line arguments */
104
  if (argcReal <= 3) {
Axel Auweter's avatar
Axel Auweter committed
105 106 107
      usage();
  }

Axel Auweter's avatar
Axel Auweter committed
108 109 110 111
  /* Allocate our lovely helper class */
  DCDBQuery* myQuery;
  myQuery = new DCDBQuery();

112
  /* Get the options */
113
  int ret;
114 115 116 117 118
  const char *host = getenv("DCDB_HOSTNAME");
  if (!host) {
      host = "localhost";
  }

Michael Ott's avatar
Michael Ott committed
119
  while ((ret=getopt(argcReal, argvReal, "+h:rlf"))!=-1) {
Axel Auweter's avatar
Axel Auweter committed
120 121 122 123
      switch(ret) {
          case 'h':
              host = optarg;
              break;
124
          case 'r':
Axel Auweter's avatar
Axel Auweter committed
125
              myQuery->setRawOutputEnabled(true);
126
              break;
127
          case 'l':
Axel Auweter's avatar
Axel Auweter committed
128
              myQuery->setLocalTimeEnabled(true);
129
              break;
Axel Auweter's avatar
Axel Auweter committed
130 131 132 133 134 135
          default:
              usage();
              exit(EXIT_FAILURE);
      }
  }

136 137
  /* Try to create TimeStamp objects from the arguments */
  DCDB::TimeStamp start, end;
Axel Auweter's avatar
Axel Auweter committed
138
  try {
139
      bool local = myQuery->getLocalTimeEnabled();
140 141
      start = DCDB::TimeStamp(argvReal[argcReal-2], local);
      end   = DCDB::TimeStamp(argvReal[argcReal-1], local);
Axel Auweter's avatar
Axel Auweter committed
142 143 144 145 146 147 148
  }
  catch (std::exception& e) {
      std::cout << "Wrong time format." << std::endl;
      exit(EXIT_FAILURE);
  }

  /* Ensure start < end */
149
  if(start > end) {
Axel Auweter's avatar
Axel Auweter committed
150 151 152 153 154 155
      std::cout << "Start time must be earlier than end time." << std::endl;
      exit(EXIT_FAILURE);
  }

  /* Build a list of sensornames */
  std::list<std::string> sensors;
156 157
  for (int arg = optind; arg < argcReal-2; arg++) {
      sensors.push_back(argvReal[arg]);
Axel Auweter's avatar
Axel Auweter committed
158 159
  }

Michael Ott's avatar
Michael Ott committed
160
  myQuery->doQuery(host, sensors, start, end);
Axel Auweter's avatar
Axel Auweter committed
161 162

  delete myQuery;
163 164 165

  return 0;
}