Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show all available data on Long-term data query log page #2202

Merged
merged 9 commits into from
May 31, 2022
33 changes: 25 additions & 8 deletions api_db.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,18 @@
{
$from = intval($_GET["from"]);
$until = intval($_GET["until"]);
$dbquery = "SELECT timestamp, type, domain, client, status, forward FROM queries WHERE timestamp >= :from AND timestamp <= :until ";

// Use table "query_storage"
// - replace domain ID with domain
// - replace client ID with client name
// - replace forward ID with forward destination
$dbquery = "SELECT timestamp, type,";
$dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,";
$dbquery .= " CASE typeof(client) WHEN 'integer' THEN (SELECT name FROM client_by_id c WHERE c.id = q.client) ELSE client END client,";
rdwebdesign marked this conversation as resolved.
Show resolved Hide resolved
$dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,";
$dbquery .= " status, reply_type, reply_time, dnssec";
$dbquery .= " FROM query_storage q";
$dbquery .= " WHERE timestamp >= :from AND timestamp <= :until ";
if(isset($_GET["types"]))
{
$types = $_GET["types"];
Expand Down Expand Up @@ -93,22 +104,28 @@

if (!is_bool($results)) {
$first = true;
while ($row = $results->fetchArray()) {
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
// Insert a comma before the next record (except on the first one)
if (!$first) {
echo ",";
} else {
$first = false;
}

// Convert query type ID to name, encode domain, encode destination
$query_type = getQueryTypeStr($row[1]);
$domain = utf8_encode(str_replace("~"," ",$row[2]));
$destination = utf8_encode($row[5]);
// Format, encode, transform each field (if necessary).
$time = $row["timestamp"];
$query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name
$domain = utf8_encode(str_replace("~"," ",$row["domain"]));
$client = $row["client"];
$status = $row["status"];
$destination = utf8_encode($row["forward"]);
$reply_type = $row["reply_type"];
$reply_time = $row["reply_time"];
$dnssec = $row["dnssec"];
$client_id = $row["client_id"];

// Insert into array and output it in JSON format
// array: time type domain client status upstream destination
echo json_encode([$row[0], $query_type, $domain, $row[3], $row[4], $destination]);
echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]);
}
}

Expand Down
2 changes: 2 additions & 0 deletions db_queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</thead>
Expand All @@ -190,6 +191,7 @@
<th>Domain</th>
<th>Client</th>
<th>Status</th>
<th>Reply</th>
<th>Action</th>
</tr>
</tfoot>
Expand Down
85 changes: 74 additions & 11 deletions scripts/pi-hole/js/db_queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ var datepickerManuallySelected = false;

var dateformat = "MMMM Do YYYY, HH:mm";

var replyTypes = [
"N/A",
"NODATA",
"NXDOMAIN",
"CNAME",
"IP",
"DOMAIN",
"RRNAME",
"SERVFAIL",
"REFUSED",
"NOTIMP",
"upstream error",
"DNSSEC",
"NONE",
"BLOB",
];

// Do we want to filter queries?
var GETDict = {};
window.location.search
Expand Down Expand Up @@ -210,6 +227,34 @@ $(function () {

tableApi = $("#all-queries").DataTable({
rowCallback: function (row, data) {
var replyid = parseInt(data[6], 10);
var dnssecStatus;
switch (data[8]) {
case "1":
dnssecStatus = '<br><span class="text-green">SECURE';
break;
case "2":
dnssecStatus = '<br><span class="text-orange">INSECURE';
break;
case "3":
dnssecStatus = '<br><span class="text-red">BOGUS';
break;
case "4":
dnssecStatus = '<br><span class="text-red">ABANDONED';
break;
case "5":
dnssecStatus = '<br><span class="text-orange">UNKNOWN';
break;
default:
// No DNSSEC
dnssecStatus = "";
}

if (dnssecStatus.length > 0) {
if (replyid === 7) dnssecStatus += " (refused upstream)";
dnssecStatus += "</span>";
}

var fieldtext,
buttontext = "",
blocked = false;
Expand All @@ -222,14 +267,16 @@ $(function () {
break;
case 2:
fieldtext =
"<span class='text-green'>OK</span> (forwarded to <br class='hidden-lg'>" +
(data.length > 5 && data[5] !== "N/A" ? data[5] : "") +
")";
replyid === 0
? "<span class='text-green'>OK</span> (sent to <br class='hidden-lg'>"
rdwebdesign marked this conversation as resolved.
Show resolved Hide resolved
: "<span class='text-green'>OK</span> (answered by <br class='hidden-lg'>";
rdwebdesign marked this conversation as resolved.
Show resolved Hide resolved
fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + dnssecStatus + ")";
buttontext =
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>';
break;
case 3:
fieldtext = "<span class='text-green'>OK</span> <br class='hidden-lg'>(cache)";
fieldtext =
"<span class='text-green'>OK</span> <br class='hidden-lg'>(cache)" + dnssecStatus;
buttontext =
'<button type="button" class="btn btn-default btn-sm text-red"><i class="fa fa-ban"></i> Blacklist</button>';
break;
Expand Down Expand Up @@ -305,13 +352,28 @@ $(function () {
fieldtext = "Unknown (" + parseInt(data[4], 10) + ")";
}

// Cannot block internal queries of this type
if ((data[1] === "DNSKEY" || data[1] === "DS") && data[3] === "pi.hole") buttontext = "";

$(row).addClass(blocked === true ? "blocked-row" : "allowed-row");
if (localStorage && localStorage.getItem("colorfulQueryLog_chkbox") === "true") {
$(row).addClass(blocked === true ? "text-red" : "text-green");
}

// Check for existence of sixth column and display only if not Pi-holed
var replytext =
replyid >= 0 && replyid < replyTypes.length ? replyTypes[replyid] : "? (" + replyid + ")";

replytext += '<input type="hidden" name="id" value="' + replyid + '">';

$("td:eq(4)", row).html(fieldtext);
$("td:eq(5)", row).html(buttontext);
$("td:eq(5)", row).html(replytext);
$("td:eq(6)", row).html(buttontext);

// Show response time only when reply is not N/A
if (data.length > 7 && replyid !== 0) {
$("td:eq(5)", row).append(" (" + (1000 * data[7]).toFixed(1) + "ms)");
}

// Substitute domain by "." if empty
var domain = data[2];
Expand Down Expand Up @@ -343,7 +405,7 @@ $(function () {
order: [[0, "desc"]],
columns: [
{
width: "15%",
width: "12%",
render: function (data, type) {
if (type === "display") {
return moment
Expand All @@ -354,11 +416,12 @@ $(function () {
return data;
},
},
{ width: "10%" },
{ width: "40%" },
{ width: "20%", type: "ip-address" },
{ width: "10%" },
{ width: "5%" },
{ width: "9%" },
{ width: "36%" },
{ width: "10%", type: "ip-address" },
{ width: "15%" },
{ width: "9%" },
{ width: "9%" },
],
lengthMenu: [
[10, 25, 50, 100, -1],
Expand Down