Skip to content

Commit

Permalink
Added the list of user agents per host to the HTML output.
Browse files Browse the repository at this point in the history
  • Loading branch information
allinurl committed May 31, 2016
1 parent 6b17b30 commit 0d20a1c
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 32 deletions.
34 changes: 26 additions & 8 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -848,12 +848,14 @@ GoAccess.Tables = {
var plotUI = GoAccess.AppCharts[panel].opts();

hide = this.toggleExpanded(panel, key);
this.renderTable(panel, this.getCurPage(panel));
if (!plotUI.redrawOnExpand)
return;

if (!hide)
data = GoAccess.Charts.processChartData(this.addChartData(panel, key));
else
data = GoAccess.Charts.processChartData(this.removeChartData(panel, key));

this.renderTable(panel, this.getCurPage(panel));
GoAccess.Charts.drawPlot(panel, plotUI, data);
},

Expand Down Expand Up @@ -963,7 +965,7 @@ GoAccess.Tables = {
// Return an object that can be consumed by the table template given a user
// interface definition and a cell value object.
// e.g., value = Object {count: 14351, percent: 5.79}
getTableCell: function (panel, ui, value) {
getObjectCell: function (panel, ui, value) {
var className = ui.className || '';
className += ui.valueType != 'string' ? 'text-right' : '';
return {
Expand All @@ -982,12 +984,12 @@ GoAccess.Tables = {
'panel' : panel,
'idx' : !subItem && (String(idx + this.pageOffSet(panel))),
'key' : !subItem ? GoAccess.Util.hashCode(dataItem.data) : '',
'expanded' : !subItem && expanded,
'parentId' : subItem ? String(parentId) : '',
'className' : subItem ? 'child ' + shadeChild : 'parent ' + shadeParent,
'cells' : this.iterUIItems(panel, ui.items, dataItem, callback),
'hasSubItems' : ui.hasSubItems,
'expanded' : !subItem && expanded,
'items' : dataItem.items ? dataItem.items.length : 0,
'cells' : callback.call(this),
};
},

Expand All @@ -1006,10 +1008,26 @@ GoAccess.Tables = {

// Iterate over all data items for the given panel and
// generate a table row per date item.
var callback = this.getTableCell.bind(this);
var cellcb = null;
for (var i = 0; i < dataItems.length; ++i) {
var dataItem = dataItems[i], expanded = this.isExpanded(panel, GoAccess.Util.hashCode(dataItem.data));
rows.push(this.renderRow(panel, callback, ui, dataItem, i, subItem, parentId, expanded));
var dataItem = dataItems[i], data = null, expanded = false;
switch(typeof dataItem) {
case 'string':
data = dataItem;
cellcb = function () {
return {
'colspan': ui.items.length + 1,
'value': data
}
};
break;
default:
data = dataItem.data;
cellcb = this.iterUIItems.bind(this, panel, ui.items, dataItem, this.getObjectCell.bind(this));
}

expanded = this.isExpanded(panel, GoAccess.Util.hashCode(data));
rows.push(this.renderRow(panel, cellcb, ui, dataItem, i, subItem, parentId, expanded));
if (dataItem.items && dataItem.items.length && expanded) {
this.renderRows(rows, panel, ui, dataItem.items, true, i, expanded);
}
Expand Down
17 changes: 17 additions & 0 deletions src/commons.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,23 @@ new_gagent_item (uint32_t size)
return item;
}

/* Clean the array of agents. */
void
free_agents_array (GAgents * agents)
{
int i;

if (agents == NULL)
return;

/* clean stuff up */
for (i = 0; i < agents->size; ++i)
free (agents->items[i].agent);
if (agents->items)
free (agents->items);
free (agents);
}

/* Determine if the given date format is a timestamp.
*
* On error, 0 is returned.
Expand Down
1 change: 1 addition & 0 deletions src/commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ extern int module_list[TOTAL_MODULES];
/* *INDENT-OFF* */
GAgentItem *new_gagent_item (uint32_t size);
GAgents *new_gagents (void);
void free_agents_array (GAgents *agents);

float get_percentage (unsigned long long total, unsigned long long hit);
int get_max_choices (void);
Expand Down
90 changes: 80 additions & 10 deletions src/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,19 @@ typedef struct GPanel_
GModule module;
void (*render) (FILE * fp, GHolder * h, GPercTotals totals,
const struct GPanel_ *);
void (*subitems) (FILE * fp, GSubList * sl, GPercTotals totals, int iisp);
void (*subitems) (FILE * fp, GHolderItem * item, GPercTotals totals,
int iisp);
} GPanel;

/* number of new lines (applicable fields) */
static int nlines = 0;

static void print_json_data (FILE * fp, GHolder * h, GPercTotals totals,
const struct GPanel_ *);
static void print_json_sub_items (FILE * fp, GSubList * sl, GPercTotals totals,
int iisp);
static void print_json_host_geo (FILE * fp, GSubList * sl, GPercTotals totals,
int iisp);
static void print_json_host_geo (FILE * fp, GHolderItem * item,
GPercTotals totals, int iisp);
static void print_json_sub_items (FILE * fp, GHolderItem * item,
GPercTotals totals, int iisp);

/* *INDENT-OFF* */
static GPanel paneling[] = {
Expand Down Expand Up @@ -751,12 +752,76 @@ print_json_block (FILE * fp, GMetrics * nmetrics, int sp)
pjson (fp, "\"");
}

/* Add the given user agent value into our array of GAgents.
*
* On error, 1 is returned.
* On success, the user agent is added to the array and 0 is returned. */
static int
fill_host_agents (void *val, void *user_data)
{
GAgents *agents = user_data;
char *agent = ht_get_host_agent_val ((*(int *) val));

if (agent == NULL)
return 1;

agents->items[agents->size].agent = agent;
agents->size++;

return 0;
}

/* Iterate over the list of agents */
static void
load_host_agents (void *list, void *user_data, GO_UNUSED int count)
{
GSLList *lst = list;
GAgents *agents = user_data;

agents->items = new_gagent_item (count);
list_foreach (lst, fill_host_agents, agents);
}

/* A wrapper function to ouput an array of user agents for each host. */
static void
process_host_agents (FILE * fp, 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 (fp, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL);

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

pclose_arr (fp, iisp, 1);

/* clean stuff up */
free_agents_array (agents);
}

/* A wrapper function to ouput children nodes. */
static void
print_json_sub_items (FILE * fp, GSubList * sl, GPercTotals totals, int iisp)
print_json_sub_items (FILE * fp, GHolderItem * item, GPercTotals totals,
int iisp)
{
GMetrics *nmetrics;
GSubItem *iter;
GSubList *sl = item->sub_list;
int i = 0, iiisp = 0, iiiisp = 0;

/* use tabs to prettify output */
Expand All @@ -780,11 +845,12 @@ print_json_sub_items (FILE * fp, GSubList * sl, GPercTotals totals, int iisp)

/* Ouput Geolocation data and the IP's hostname. */
static void
print_json_host_geo (FILE * fp, GSubList * sl, GO_UNUSED GPercTotals totals,
int iisp)
print_json_host_geo (FILE * fp, GHolderItem * item,
GO_UNUSED GPercTotals totals, int iisp)
{
int i;
GSubItem *iter;
GSubList *sl = item->sub_list;
int i;
static const char *key[] = {
"country",
"city",
Expand All @@ -802,6 +868,10 @@ print_json_host_geo (FILE * fp, GSubList * sl, GO_UNUSED GPercTotals totals,
escape_json_output (fp, iter->metrics->data);
pjson (fp, (i != sl->size - 1) ? "\",%.*s" : "\"", nlines, NL);
}

/* print list of user agents */
if (conf.list_agents)
process_host_agents (fp, item, iisp);
}

/* Ouput data and determine if there are children nodes. */
Expand All @@ -827,7 +897,7 @@ print_data_metrics (FILE * fp, GHolder * h, GPercTotals totals, int sp,
print_json_block (fp, nmetrics, iiisp);
/* if there are children notes, spit them out */
if (panel->subitems && h->sub_items_size)
panel->subitems (fp, h->items[i].sub_list, totals, iiisp);
panel->subitems (fp, h->items + i, totals, iiisp);
/* close data metric block */
pclose_obj (fp, iisp, (i == h->idx - 1));

Expand Down
30 changes: 16 additions & 14 deletions src/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,41 +71,41 @@ static void print_host_metrics (FILE * fp, const GHTML * def, int sp);
/* *INDENT-OFF* */
static GHTML htmldef[] = {
{VISITORS , 1, print_metrics, {
{CHART_AREASPLINE, hits_visitors_plot, 1} ,
{CHART_AREASPLINE, hits_bw_plot, 1} ,
{CHART_AREASPLINE, hits_visitors_plot, 1, 1} ,
{CHART_AREASPLINE, hits_bw_plot, 1, 1} ,
}},
{REQUESTS , 1, print_metrics } ,
{REQUESTS_STATIC , 1, print_metrics } ,
{NOT_FOUND , 1, print_metrics } ,
{HOSTS , 1, print_host_metrics, {
{CHART_VBAR, hits_visitors_plot, 0},
{CHART_VBAR, hits_bw_plot, 0},
{CHART_VBAR, hits_visitors_plot, 0, 0},
{CHART_VBAR, hits_bw_plot, 0, 0},
}},
{OS , 1, print_metrics, {
{CHART_VBAR, hits_visitors_plot, 0},
{CHART_VBAR, hits_bw_plot, 0},
{CHART_VBAR, hits_visitors_plot, 0, 1},
{CHART_VBAR, hits_bw_plot, 0, 1},
}},
{BROWSERS , 1, print_metrics, {
{CHART_VBAR, hits_visitors_plot, 0},
{CHART_VBAR, hits_bw_plot, 0},
{CHART_VBAR, hits_visitors_plot, 0, 1},
{CHART_VBAR, hits_bw_plot, 0, 1},
}},
{VISIT_TIMES , 1, print_metrics, {
{CHART_AREASPLINE, hits_visitors_plot, 0},
{CHART_AREASPLINE, hits_bw_plot, 0},
{CHART_AREASPLINE, hits_visitors_plot, 0, 1},
{CHART_AREASPLINE, hits_bw_plot, 0, 1},
}},
{VIRTUAL_HOSTS , 1, print_metrics } ,
{REFERRERS , 1, print_metrics } ,
{REFERRING_SITES , 1, print_metrics } ,
{KEYPHRASES , 1, print_metrics } ,
#ifdef HAVE_LIBGEOIP
{GEO_LOCATION , 1, print_metrics, {
{CHART_VBAR, hits_visitors_plot, 0},
{CHART_VBAR, hits_bw_plot, 0},
{CHART_VBAR, hits_visitors_plot, 0, 1},
{CHART_VBAR, hits_bw_plot, 0, 1},
}},
#endif
{STATUS_CODES , 1, print_metrics, {
{CHART_VBAR, hits_visitors_plot, 0},
{CHART_VBAR, hits_bw_plot, 0},
{CHART_VBAR, hits_visitors_plot, 0, 1},
{CHART_VBAR, hits_bw_plot, 0, 1},
}},
};
/* *INDENT-ON* */
Expand Down Expand Up @@ -316,6 +316,7 @@ hits_visitors_plot (FILE * fp, const GHTMLPlot plot, int sp)
pskeysval (fp, "className", "hits-visitors", isp, 0);
pskeysval (fp, "chartType", chart2str (plot.chart_type), isp, 0);
pskeyival (fp, "chartReverse", plot.chart_reverse, isp, 0);
pskeyival (fp, "redrawOnExpand", plot.redraw_expand, isp, 0);

/* D3.js data */
popen_obj_attr (fp, "d3", isp);
Expand Down Expand Up @@ -346,6 +347,7 @@ hits_bw_plot (FILE * fp, const GHTMLPlot plot, int sp)
pskeysval (fp, "className", "bandwidth", isp, 0);
pskeysval (fp, "chartType", chart2str (plot.chart_type), isp, 0);
pskeyival (fp, "chartReverse", plot.chart_reverse, isp, 0);
pskeyival (fp, "redrawOnExpand", plot.redraw_expand, isp, 0);

/* D3.js data */
popen_obj_attr (fp, "d3", isp);
Expand Down
1 change: 1 addition & 0 deletions src/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef struct GHTMLPlot_
GChartType chart_type;
void (*plot) (FILE * fp, const struct GHTMLPlot_ plot, int sp);
int8_t chart_reverse;
int8_t redraw_expand;
} GHTMLPlot;
/* Controls HTML output. */
typedef struct GHTML_
Expand Down

0 comments on commit 0d20a1c

Please sign in to comment.