Commit 1a57bff6 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

Merge remote-tracking branch 'github/adminui_singleMetricView' into fnordmetric2

parents 98a5a352 b4a03ce1
Loading
Loading
Loading
Loading
+110 −102
Original line number Diff line number Diff line
@@ -26,156 +26,166 @@ target_port = ARGV[1].to_i

loop do
  last_run = Time.now.to_f
  samples = []
  @samples = []

  # hostname
  hostname = `hostname`.strip
  @hostname = `hostname`.strip


  # collect CPU load averages

  def report_cpu_load

    if File.exists?("/proc/loadavg")
      loadavg_data = IO::read("/proc/loadavg")

      loadavg = loadavg_data.scan(/([0-9]+[,\.][0-9]+)+/).flatten

      if loadavg.size == 3
      samples << {
        @samples << {
          :metric => "load_avg_1m",
          :value => loadavg[0],
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }

      samples << {
        @samples << {
          :metric => "load_avg_5m",
          :value => loadavg[1],
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }

      samples << {
        @samples << {
          :metric => "load_avg_15m",
          :value => loadavg[2],
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }
      end
    end
  end

  # gather basic memory statistics

  def report_memory_stats
    if File.exists?("/proc/meminfo")
      loadavg_data = IO::read("/proc/meminfo")
    memtotal  = loadavg_data.scan(/MemTotal:\s+ (\d+)\skB/).flatten
    memfree   = loadavg_data.scan(/MemFree:\s+ (\d+)\skB/).flatten
    swaptotal = loadavg_data.scan(/SwapTotal:\s+ (\d+)\skB/).flatten
    swapfree  = loadavg_data.scan(/SwapFree:\s+ (\d+)\skB/).flatten
      memtotal  = loadavg_data.scan(/MemTotal:\s+ (\d+)\skB/).flatten.first.to_i
      memfree   = loadavg_data.scan(/MemFree:\s+ (\d+)\skB/).flatten.first.to_i
      swaptotal = loadavg_data.scan(/SwapTotal:\s+ (\d+)\skB/).flatten.first.to_i
      swapfree  = loadavg_data.scan(/SwapFree:\s+ (\d+)\skB/).flatten.first.to_i

      samples << {
        @samples << {
          :metric => "memory_total",
          :value => memtotal,
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }

      samples << {
        @samples << {
          :metric => "memory_free",
          :value => memfree,
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }

      samples << {
        @samples << {
          :metric => "swap_total",
          :value => swaptotal,
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }

      samples << {
        :metric => "swap_total",
        @samples << {
          :metric => "swap_free",
          :value => swapfree,
          :labels => {
          :host => hostname
            :host => @hostname
          }
        }


    end
  end

  # determine disk usage and available space

  def report_disk_stats

    df_input = `df -P`.lines[1..-1]

    if !df_input.empty?
   df_input.each { |single_line|
     df_input.each do |single_line|
      elements = single_line.split " "

        samples << {
          @samples << {
          :metric => "disk_used",
          :value => elements[2],
          :labels => {
          :host => hostname,
            :host => @hostname,
            :mount_name => elements[0]
          }
        }

        samples << {
          @samples << {
          :metric => "disk_available",
          :value => elements[3],
          :labels => {
          :host => hostname,
            :host => @hostname,
            :mount_name => elements[0]
          }
        }
    }
     end

    end
  end

  #count open TCP and UDP sockets

  if File.exists?("/proc/net/tcp")
   loadavg_data = IO::read("/proc/net/tcp")
  def report_open_sockets

    if File.exists?("/proc/net/tcp")
     tcp_sockets =  %x{wc -l "/proc/net/tcp"}.to_i - 1

    samples << {
      @samples << {
        :metric => "open_tcp_sockets",
        :value => tcp_sockets,
        :labels => {
        :host => hostname
          :host => @hostname
        }
      }


    end

    if File.exists?("/proc/net/udp")
    loadavg_data = IO::read("/proc/net/udp")

     tcp_sockets =  %x{wc -l "/proc/net/udp"}.to_i - 1

    samples << {
      @samples << {
        :metric => "open_udp_sockets",
        :value => tcp_sockets,
        :labels => {
        :host => hostname
          :host => @hostname
        }
      }


    end
  end

  # fill samples array with data

  report_memory_stats
  report_disk_stats
  report_cpu_load
  report_open_sockets

  # send the samples in a single udp packet to FnordMetric server (the combined
  # packet size must be strictly less than or equal to 65535 bytes
  packet = ""
  samples.each do |sample|
  @samples.each do |sample|
    packet << METRIC_NAME_PREFIX + sample[:metric]
    sample[:labels].each do |k,v|
      packet << "[#{k}=#{v}]"
@@ -195,5 +205,3 @@ loop do
  sleep_for = (last_run + INTERVAL) - Time.now.to_f
  sleep(sleep_for) if sleep_for > 0
end
end
end
+15 −0
Original line number Diff line number Diff line
@@ -30,8 +30,10 @@ void eqExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() == rhs->getInteger());
          return;
        case SValue::T_FLOAT:
@@ -45,6 +47,7 @@ void eqExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() == rhs->getFloat());
          return;
        default:
@@ -167,8 +170,10 @@ void ltExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() < rhs->getInteger());
          return;
        case SValue::T_FLOAT:
@@ -182,6 +187,7 @@ void ltExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() < rhs->getFloat());
          return;
        default:
@@ -215,8 +221,10 @@ void lteExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() <= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
@@ -230,6 +238,7 @@ void lteExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() <= rhs->getFloat());
          return;
        default:
@@ -263,8 +272,10 @@ void gtExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() > rhs->getInteger());
          return;
        case SValue::T_FLOAT:
@@ -278,6 +289,7 @@ void gtExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() > rhs->getFloat());
          return;
        default:
@@ -311,8 +323,10 @@ void gteExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {

  switch(lhs->testTypeWithNumericConversion()) {
    case SValue::T_INTEGER:
    case SValue::T_TIMESTAMP:
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getInteger() >= rhs->getInteger());
          return;
        case SValue::T_FLOAT:
@@ -326,6 +340,7 @@ void gteExpr(void* scratchpad, int argc, SValue* argv, SValue* out) {
      switch(rhs->testTypeWithNumericConversion()) {
        case SValue::T_INTEGER:
        case SValue::T_FLOAT:
        case SValue::T_TIMESTAMP:
          *out = SValue(lhs->getFloat() >= rhs->getFloat());
          return;
        default:
+4 −0
Original line number Diff line number Diff line
@@ -108,6 +108,10 @@ ASTNode* ASTNode::deepCopy() const {
  }

  for (const auto child : children_) {
    if (child == nullptr) {
      continue;
    }

    copy->appendChild(child->deepCopy());
  }

+58 −0
Original line number Diff line number Diff line
@@ -1252,3 +1252,61 @@ TEST_CASE(SQLTest, TestSimpleGroupOverTimeWindow, [] () {
  EXPECT_EQ(result->getRow(15)[1], "NULL");
  EXPECT_EQ(result->getRow(28)[1], "28170");
});

TEST_CASE(SQLTest, TestNumericConversion, [] () {
  {
    SValue val("42");
    EXPECT_EQ(val.getType(), SValue::T_STRING);
    EXPECT(val.testType<fnordmetric::IntegerType>());
    EXPECT(val.tryNumericConversion());
    EXPECT_EQ(val.getInteger(), 42);
  }

  {
    SValue val("1415912541648");
    EXPECT_EQ(val.getType(), SValue::T_STRING);
    EXPECT(val.testType<fnordmetric::IntegerType>());
    EXPECT(val.tryNumericConversion());
    EXPECT_EQ(val.getInteger(), 1415912541648lu);
  }
});

TEST_CASE(SQLTest, TestCompareTimestamps, [] () {
  auto result = executeTestQuery(
      "  SELECT"
      "  FROM_TIMESTAMP(1415916005281) > FROM_TIMESTAMP(1415916005281) as a,"
      "  FROM_TIMESTAMP(1415916005281) < FROM_TIMESTAMP(1415916005281) as b,"
      "  FROM_TIMESTAMP(1415916005282) > FROM_TIMESTAMP(1415916005281) as c,"
      "  FROM_TIMESTAMP(1415916005280) < FROM_TIMESTAMP(1415916005281) as d,"
      "  FROM_TIMESTAMP(1415916005280) > FROM_TIMESTAMP(1415916005281) as e,"
      "  FROM_TIMESTAMP(1415916005282) < FROM_TIMESTAMP(1415916005281) as f;");

  EXPECT_EQ(result->getNumRows(), 1);
  EXPECT_EQ(result->getNumColumns(), 6);
  EXPECT_EQ(result->getRow(0)[0], "false");
  EXPECT_EQ(result->getRow(0)[1], "false");
  EXPECT_EQ(result->getRow(0)[2], "true");
  EXPECT_EQ(result->getRow(0)[3], "true");
  EXPECT_EQ(result->getRow(0)[4], "false");
  EXPECT_EQ(result->getRow(0)[5], "false");
});

TEST_CASE(SQLTest, TestInvalidQueries, [] () {
  std::vector<std::string> queries;

  queries.push_back(
      "SELECT time AS x, count(value) as y FROM `http_status_codes`"
      "where GROUP OVER TIMEWINDOW(time, 1000, 1) BY test;");

  for (const auto& query : queries) {
    bool raised = false;

    try {
      executeTestQuery(query.c_str());
    } catch (std::exception& e) {
      raised = true;
    }

    EXPECT(raised);
  }
});
+36 −11
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <fnordmetric/sql/parser/token.h>
#include <fnordmetric/sql/svalue.h>
#include <fnordmetric/util/format.h>
#include <fnordmetric/util/inspect.h>

namespace fnordmetric {
namespace query {
@@ -44,22 +45,26 @@ SValue::SValue(const fnordmetric::StringType& string_value) {
      data_.u.t_string.len);
}

SValue::SValue(fnordmetric::IntegerType integer_value) : SValue() {
SValue::SValue(
    char const* string_value) :
    SValue(std::string(string_value)) {}

SValue::SValue(fnordmetric::IntegerType integer_value) {
  data_.type = T_INTEGER;
  data_.u.t_integer = integer_value;
}

SValue::SValue(fnordmetric::FloatType float_value) : SValue() {
SValue::SValue(fnordmetric::FloatType float_value) {
  data_.type = T_FLOAT;
  data_.u.t_float = float_value;
}

SValue::SValue(fnordmetric::BoolType bool_value) : SValue() {
SValue::SValue(fnordmetric::BoolType bool_value) {
  data_.type = T_BOOL;
  data_.u.t_bool = bool_value;
}

SValue::SValue(fnordmetric::TimeType time_value) : SValue() {
SValue::SValue(fnordmetric::TimeType time_value) {
  data_.type = T_TIMESTAMP;
  data_.u.t_timestamp = static_cast<uint64_t>(time_value);
}
@@ -145,9 +150,12 @@ fnordmetric::IntegerType SValue::getInteger() const {
    case T_INTEGER:
      return data_.u.t_integer;

    case T_TIMESTAMP:
      return data_.u.t_timestamp;

    case T_STRING:
      try {
        return std::stoi(getString());
        return std::stol(getString());
      } catch (std::exception e) {
        /* fallthrough */
      }
@@ -155,7 +163,7 @@ fnordmetric::IntegerType SValue::getInteger() const {
    default:
      RAISE(
          kTypeError,
          "can't convert %s '%s' to Float",
          "can't convert %s '%s' to Integer",
          SValue::getTypeName(data_.type),
          toString().c_str());

@@ -373,14 +381,19 @@ template <> bool SValue::testType<fnordmetric::IntegerType>() const {
  }

  auto str = toString();
  const char* c = str.c_str();
  const char* cur = str.c_str();
  const char* end = cur + str.size();

  if (*c == '-') {
    ++c;
  if (*cur == '-') {
    ++cur;
  }

  for (; *c != 0; ++c) {
    if (*c < '0' || *c > '9') {
  if (cur == end) {
    return false;
  }

  for (; cur < end; ++cur) {
    if (*cur < '0' || *cur > '9') {
      return false;
    }
  }
@@ -462,5 +475,17 @@ bool SValue::tryTimeConversion() {
}


}
}

namespace fnord {
namespace util {

template <>
std::string inspect<fnordmetric::query::SValue::kSValueType>(
    const fnordmetric::query::SValue::kSValueType& type) {
  return fnordmetric::query::SValue::getTypeName(type);
}

}
}
Loading