コード例 #1
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* A wrapper function to ouput an array of user agents for each host. */
static void
process_host_agents (GJSON * json, GHolderItem * item, int iisp)
{
  GAgents *agents = new_gagents ();
  int i, n = 0, iiisp = 0;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    iiisp = iisp + 1;

  if (set_host_agents (item->metrics->data, load_host_agents, agents) == 1)
    return;

  pjson (json, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL);

  n = agents->size > 10 ? 10 : agents->size;
  for (i = 0; i < n; ++i) {
    pjson (json, "%.*s\"", iiisp, TAB);
    escape_json_output (json, agents->items[i].agent);
    if (i == n - 1)
      pjson (json, "\"");
    else
      pjson (json, "\",%.*s", nlines, NL);
  }

  pclose_arr (json, iisp, 1);

  /* clean stuff up */
  free_agents_array (agents);
}
コード例 #2
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Entry point to generate a a json report writing it to the fp */
void
output_json (GLog * logger, GHolder * holder)
{
  FILE *fp = stdout;
  GModule module;

  GPercTotals totals = {
    .hits = logger->valid,
    .visitors = ht_get_size_uniqmap (VISITORS),
    .bw = logger->resp_size,
  };

  /* use new lines to prettify output */
  if (conf.json_pretty_print)
    nlines = 1;

  pjson (fp, "{%.*s", nlines, NL);
  print_json_summary (fp, logger);

  for (module = 0; module < TOTAL_MODULES; module++) {
    const GPanel *panel = panel_lookup (module);
    if (!panel)
      continue;
    if (ignore_panel (module))
      continue;

    panel->render (fp, holder + module, totals, panel);
    pjson (fp, (module != TOTAL_MODULES - 1) ? ",%.*s" : "%.*s", nlines, NL);
  }
  pjson (fp, "}");

  fclose (fp);
}
コード例 #3
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* A wrapper function to ouput children nodes. */
static void
print_json_sub_items (FILE * fp, GSubList * sl, GPercTotals totals, int iisp)
{
  GMetrics *nmetrics;
  GSubItem *iter;
  char comma = ' ';
  int i = 0, iiisp = 0, iiiisp = 0;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    iiisp = iisp + 1, iiiisp = iiisp + 1;

  if (sl == NULL)
    return;

  pjson (fp, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL);
  for (iter = sl->head; iter; iter = iter->next, i++) {
    set_data_metrics (iter->metrics, &nmetrics, totals);

    pjson (fp, "%.*s{%.*s", iiisp, TAB, nlines, NL);
    print_json_block (fp, nmetrics, iiiisp);
    comma = (i != sl->size - 1) ? ',' : ' ';
    pjson (fp, "%.*s%.*s}%c%.*s", nlines, NL, iiisp, TAB, comma, nlines, NL);
    free (nmetrics);
  }
  pjson (fp, "%.*s]", iisp, TAB);
}
コード例 #4
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Close the data array. */
static void
pclose_arr (GJSON * json, int sp, int last)
{
  if (!last)
    pjson (json, "%.*s%.*s],%.*s", nlines, NL, sp, TAB, nlines, NL);
  else
    pjson (json, "%.*s%.*s]", nlines, NL, sp, TAB);
}
コード例 #5
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Write to a buffer a JSON string key, uint64_t value pair. */
static void
pskeyu64val (GJSON * json, const char *key, uint64_t val, int sp, int last)
{
  if (!last)
    pjson (json, "%.*s\"%s\": %" PRIu64 ",%.*s", sp, TAB, key, val, nlines, NL);
  else
    pjson (json, "%.*s\"%s\": %" PRIu64 "", sp, TAB, key, val);
}
コード例 #6
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Close JSON object. */
static void
pclose_obj (GJSON * json, int iisp, int last)
{
  if (!last)
    pjson (json, "%.*s%.*s},%.*s", nlines, NL, iisp, TAB, nlines, NL);
  else
    pjson (json, "%.*s%.*s}", nlines, NL, iisp, TAB);
}
コード例 #7
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Write to a buffer a JSON string key, int value pair. */
static void
pskeyfval (GJSON * json, const char *key, float val, int sp, int last)
{
  if (!last)
    pjson (json, "%.*s\"%s\": \"%4.2f\",%.*s", sp, TAB, key, val, nlines, NL);
  else
    pjson (json, "%.*s\"%s\": \"%4.2f\"", sp, TAB, key, val);
}
コード例 #8
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Write to a buffer a JSON string key, int value pair. */
static void
pskeyival (GJSON * json, const char *key, int val, int sp, int last)
{
  if (!last)
    pjson (json, "%.*s\"%s\": %d,%.*s", sp, TAB, key, val, nlines, NL);
  else
    pjson (json, "%.*s\"%s\": %d", sp, TAB, key, val);
}
コード例 #9
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the path of the log being parsed under the overall object.
 *
 * On success, data is outputted. */
static void
poverall_log (FILE * fp, int isp)
{
  if (conf.ifile == NULL)
    conf.ifile = (char *) "STDIN";
  pjson (fp, "%.*s\"%s\": \"", isp, TAB, OVERALL_LOG);
  escape_json_output (fp, conf.ifile);
  pjson (fp, "\"%.*s", nlines, NL);
}
コード例 #10
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
static void
poverall_log_path (GJSON * json, int idx, int isp)
{
  pjson (json, "%.*s\"", isp, TAB);
  if (conf.filenames[idx][0] == '-' && conf.filenames[idx][1] == '\0')
    pjson (json, "STDIN");
  else
    escape_json_output (json, (char *) conf.filenames[idx]);
  pjson (json, conf.filenames_idx - 1 != idx ? "\",\n" : "\"");
}
コード例 #11
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the visitors meta data object.
 *
 * If no metadata found, it simply returns.
 * On success, meta data is outputted. */
static void
pmeta_data_visitors (FILE * fp, GModule module, int sp)
{
  int isp = 0;
  uint64_t count = ht_get_meta_data (module, "visitors");

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    isp = sp + 1;

  pjson (fp, "%.*s\"visitors\": {%.*s", sp, TAB, nlines, NL);
  pjson (fp, "%.*s\"count\": %lld%.*s", isp, TAB, (long long) count, nlines,
         NL);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #12
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the number of invalid requests under the overall object.
 *
 * On success, data is outputted. */
static void
poverall_invalid_reqs (FILE * fp, GLog * logger, int isp)
{
  int total = logger->invalid;
  pjson (fp, "%.*s\"%s\": %d,%.*s", isp, TAB, OVERALL_FAILED, total, nlines,
         NL);
}
コード例 #13
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the number of static files (jpg, pdf, etc) under the overall
 * object.
 *
 * On success, data is outputted. */
static void
poverall_static_files (FILE * fp, int isp)
{
  int total = ht_get_size_datamap (REQUESTS_STATIC);
  pjson (fp, "%.*s\"%s\": %d,%.*s", isp, TAB, OVERALL_STATIC, total, nlines,
         NL);
}
コード例 #14
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the number of not found (404s) under the overall object.
 *
 * On success, data is outputted. */
static void
poverall_notfound (FILE * fp, int isp)
{
  int total = ht_get_size_datamap (NOT_FOUND);
  pjson (fp, "%.*s\"%s\": %d,%.*s", isp, TAB, OVERALL_NOTFOUND, total, nlines,
         NL);
}
コード例 #15
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the total number of excluded requests under the overall
 * object.
 *
 * On success, data is outputted. */
static void
poverall_excluded (FILE * fp, GLog * logger, int isp)
{
  int total = logger->excluded_ip;
  pjson (fp, "%.*s\"%s\": %d,%.*s", isp, TAB, OVERALL_EXCL_HITS, total, nlines,
         NL);
}
コード例 #16
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the total number of unique visitors under the overall
 * object.
 *
 * On success, data is outputted. */
static void
poverall_visitors (FILE * fp, int isp)
{
  int total = ht_get_size_uniqmap (VISITORS);
  pjson (fp, "%.*s\"%s\": %d,%.*s", isp, TAB, OVERALL_VISITORS, total, nlines,
         NL);
}
コード例 #17
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* A wrapper function to ouput children nodes. */
static void
print_json_sub_items (GJSON * json, GHolderItem * item, GPercTotals totals,
                      int size, int iisp)
{
  GMetrics *nmetrics;
  GSubItem *iter;
  GSubList *sl = item->sub_list;
  int i = 0, iiisp = 0, iiiisp = 0;

  /* no sub items, nothing to output */
  if (size == 0)
    return;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    iiisp = iisp + 1, iiiisp = iiisp + 1;

  if (sl == NULL)
    return;

  pjson (json, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL);
  for (iter = sl->head; iter; iter = iter->next, i++) {
    set_data_metrics (iter->metrics, &nmetrics, totals);

    popen_obj (json, iiisp);
    print_json_block (json, nmetrics, iiiisp);
    pclose_obj (json, iiisp, (i == sl->size - 1));
    free (nmetrics);
  }
  pclose_arr (json, iisp, 1);
}
コード例 #18
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output maximum time served data.
 *
 * On success, data is outputted. */
static void
pmaxts (FILE * fp, GMetrics * nmetrics, int sp)
{
  if (!conf.serve_usecs)
    return;
  pjson (fp, "%.*s\"maxts\": %lld,%.*s", sp, TAB,
         (long long) nmetrics->maxts.nts, nlines, NL);
}
コード例 #19
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output hits data.
 *
 * On success, data is outputted. */
static void
phits (FILE * fp, GMetrics * nmetrics, int sp)
{
  int isp = 0;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    isp = sp + 1;

  pjson (fp, "%.*s\"hits\": {%.*s", sp, TAB, nlines, NL);
  /* print hits */
  pjson (fp, "%.*s\"count\": %d,%.*s", isp, TAB, nmetrics->hits, nlines, NL);
  /* print hits percent */
  pjson (fp, "%.*s\"percent\": %4.2f%.*s", isp, TAB, nmetrics->hits_perc,
         nlines, NL);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #20
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output request method data.
 *
 * On success, data is outputted. */
static void
pmethod (FILE * fp, GMetrics * nmetrics, int sp)
{
  /* request method */
  if (conf.append_method && nmetrics->method) {
    pjson (fp, "%.*s\"method\": \"%s\",%.*s", sp, TAB, nmetrics->method, nlines,
           NL);
  }
}
コード例 #21
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output protocol method data.
 *
 * On success, data is outputted. */
static void
pprotocol (FILE * fp, GMetrics * nmetrics, int sp)
{
  /* request protocol */
  if (conf.append_protocol && nmetrics->protocol) {
    pjson (fp, "%.*s\"protocol\": \"%s\",%.*s", sp, TAB, nmetrics->protocol,
           nlines, NL);
  }
}
コード例 #22
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the size of the log being parsed under the overall object.
 *
 * On success, data is outputted. */
static void
poverall_log_size (FILE * fp, GLog * logger, int isp)
{
  off_t log_size = 0;

  if (!logger->piping && conf.ifile)
    log_size = file_size (conf.ifile);
  pjson (fp, "%.*s\"%s\": %jd,%.*s", isp, TAB, OVERALL_LOGSIZE,
         (intmax_t) log_size, nlines, NL);
}
コード例 #23
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the maximum time served meta data object.
 *
 * If no metadata found, it simply returns.
 * On success, meta data is outputted. */
static void
pmeta_data_maxts (FILE * fp, GModule module, int sp)
{
  int isp = 0;
  uint64_t count = 0;

  if (!conf.serve_usecs)
    return;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    isp = sp + 1;

  count = ht_get_meta_data (module, "maxts");
  pjson (fp, "%.*s\"maxts\": {%.*s", sp, TAB, nlines, NL);
  pjson (fp, "%.*s\"count\": %lld%.*s", isp, TAB, (long long) count, nlines,
         NL);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #24
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output bandwidth data.
 *
 * On success, data is outputted. */
static void
pbw (FILE * fp, GMetrics * nmetrics, int sp)
{
  int isp = 0;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    isp = sp + 1;

  if (!conf.bandwidth)
    return;

  pjson (fp, "%.*s\"bytes\": {%.*s", sp, TAB, nlines, NL);
  /* print bandwidth */
  pjson (fp, "%.*s\"count\": %d,%.*s", isp, TAB, nmetrics->bw.nbw, nlines, NL);
  /* print bandwidth percent */
  pjson (fp, "%.*s\"percent\": %4.2f%.*s", isp, TAB, nmetrics->bw_perc, nlines,
         NL);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #25
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output date and time for the overall object.
 *
 * On success, data is outputted. */
static void
poverall_datetime (FILE * fp, int isp)
{
  char now[DATE_TIME];

  generate_time ();
  strftime (now, DATE_TIME, "%Y-%m-%d %H:%M:%S", now_tm);

  pjson (fp, "%.*s\"%s\": \"%s\",%.*s", isp, TAB, OVERALL_DATETIME, now, nlines,
         NL);
}
コード例 #26
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* A wrapper function to ouput geolocation fields for the given host. */
static void
print_json_host_geo (GJSON * json, GSubList * sl, int iisp)
{
  GSubItem *iter;
  int i;
  static const char *key[] = {
    "country",
    "city",
    "hostname",
  };

  pjson (json, ",%.*s", nlines, NL);

  /* Iterate over child properties (country, city, etc) and print them out */
  for (i = 0, iter = sl->head; iter; iter = iter->next, i++) {
    pjson (json, "%.*s\"%s\": \"", iisp, TAB, key[iter->metrics->id]);
    escape_json_output (json, iter->metrics->data);
    pjson (json, (i != sl->size - 1) ? "\",%.*s" : "\"", nlines, NL);
  }
}
コード例 #27
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* Escape all other characters accordingly. */
static void
escape_json_other (GJSON * json, char **s)
{
  /* Since JSON data is bootstrapped into the HTML document of a report,
   * then we perform the following four translations in case weird stuff
   * is put into the document.
   *
   * Note: The following scenario assumes that the user manually makes
   * the HTML report a PHP file (GoAccess doesn't allow the creation of a
   * PHP file):
   *
   * /index.html<?php eval(base_decode('iZWNobyAiPGgxPkhFTExPPC9oMT4iOw=='));?>
   */
  if (escape_html_output) {
    switch (**s) {
    case '\'':
      pjson (json, "&#39;");
      return;
    case '&':
      pjson (json, "&amp;");
      return;
    case '<':
      pjson (json, "&lt;");
      return;
    case '>':
      pjson (json, "&gt;");
      return;
    }
  }

  if ((uint8_t) ** s <= 0x1f) {
    /* Control characters (U+0000 through U+001F) */
    char buf[8];
    snprintf (buf, sizeof buf, "\\u%04x", **s);
    pjson (json, "%s", buf);
  } else if ((uint8_t) ** s == 0xe2 && (uint8_t) * (*s + 1) == 0x80 &&
             (uint8_t) * (*s + 2) == 0xa8) {
    /* Line separator (U+2028) - 0xE2 0x80 0xA8 */
    pjson (json, "\\u2028");
    *s += 2;
  } else if ((uint8_t) ** s == 0xe2 && (uint8_t) * (*s + 1) == 0x80 &&
             (uint8_t) * (*s + 2) == 0xa9) {
    /* Paragraph separator (U+2019) - 0xE2 0x80 0xA9 */
    pjson (json, "\\u2029");
    *s += 2;
  } else {
    char buf[2];
    snprintf (buf, sizeof buf, "%c", **s);
    pjson (json, "%s", buf);
  }
}
コード例 #28
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output overall data. */
static void
print_json_summary (FILE * fp, GLog * logger)
{
  int sp = 0, isp = 0;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    sp = 1, isp = 2;

  pjson (fp, "%.*s\"%s\": {%.*s", sp, TAB, GENER_ID, nlines, NL);
  /* generated date time */
  poverall_datetime (fp, isp);
  /* total requests */
  poverall_requests (fp, logger, isp);
  /* valid requests */
  poverall_valid_reqs (fp, logger, isp);
  /* invalid requests */
  poverall_invalid_reqs (fp, logger, isp);
  /* generated time */
  poverall_processed_time (fp, isp);
  /* visitors */
  poverall_visitors (fp, isp);
  /* files */
  poverall_files (fp, isp);
  /* excluded hits */
  poverall_excluded (fp, logger, isp);
  /* referrers */
  poverall_refs (fp, isp);
  /* not found */
  poverall_notfound (fp, isp);
  /* static files */
  poverall_static_files (fp, isp);
  /* log size */
  poverall_log_size (fp, logger, isp);
  /* bandwidth */
  poverall_bandwidth (fp, logger, isp);
  /* log path */
  poverall_log (fp, isp);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #29
0
ファイル: json.c プロジェクト: 0-T-0/goaccess
/* Output the average of the average time served meta data object.
 *
 * If no metadata found, it simply returns.
 * On success, meta data is outputted. */
static void
pmeta_data_avgts (FILE * fp, GModule module, int sp)
{
  int isp = 0;
  uint64_t avg = 0, hits = 0, cumts = 0;

  if (!conf.serve_usecs)
    return;

  /* use tabs to prettify output */
  if (conf.json_pretty_print)
    isp = sp + 1;

  cumts = ht_get_meta_data (module, "cumts");
  hits = ht_get_meta_data (module, "hits");
  if (hits > 0)
    avg = cumts / hits;

  pjson (fp, "%.*s\"avgts\": {%.*s", sp, TAB, nlines, NL);
  pjson (fp, "%.*s\"avg\": %lld%.*s", isp, TAB, (long long) avg, nlines, NL);
  pjson (fp, "%.*s},%.*s", sp, TAB, nlines, NL);
}
コード例 #30
0
ファイル: json.c プロジェクト: aishikoyo/goaccess
/* A wrapper function to ouput data metrics per panel. */
static void
print_json_block (GJSON * json, GMetrics * nmetrics, int sp)
{
  /* print hits */
  phits (json, nmetrics, sp);
  /* print visitors */
  pvisitors (json, nmetrics, sp);
  /* print bandwidth */
  pbw (json, nmetrics, sp);

  /* print time served metrics */
  pavgts (json, nmetrics, sp);
  pcumts (json, nmetrics, sp);
  pmaxts (json, nmetrics, sp);

  /* print protocol/method */
  pmethod (json, nmetrics, sp);
  pprotocol (json, nmetrics, sp);

  /* data metric */
  pjson (json, "%.*s\"data\": \"", sp, TAB);
  escape_json_output (json, nmetrics->data);
  pjson (json, "\"");
}