This tutorial shows you how to add the “next_page_key” parameter to Raw Log API responses that lets you navigate back and forth between pages. Unlike other API responses, Raw Log API responses show no total pages. So this is the only parameter we can use as an indicator of whether there is a next page or not.

If there is a value within the “next_page_key” we can anticipate the next page and generate a NEXT page button.

The API response structure is as follows:

{ "limit": 10, "page": 7, "request_time": 239, "next_page_key": "1436991333774", "records": [ {{ 
    "bytes": 185, 
    "byte_range": "-", 
    "client_asn": "AS24940 Hetzner Online AG", 
    "client_city": "-", 
    "client_continent": "EU", 
    "client_country": "DE", 
    "client_dma": "", 
    "client_ip": "178.63.10.145", 
    "client_latitude": 51, 
    "client_longitude": 9, 
    "client_state": "-", 
    "company_id": 11975, 
    "edge_host": "", 
    "cache_status": "", 
    "hostname": "www.maxcdn.com", 
    "method": "GET", 
    "origin_time": 0, 
    "pop": "fra", 
    "protocol": 
    "HTTP/1.0", 
    "query_string": "", 
    "referer": "-", 
    "request_time": 0.006, 
    "scheme": "http", 
    "status": 301, 
    "time": "2015-07-15T20:15:33.774Z", 
    "uri": "/", 
    "user_agent": "Mozilla/5.0 (compatible; www.monitor.us - free monitoring service; http://www.monitor.us)", 
    "zone_id": 188668 },
    {
    …
    }
] }

With knowledge of the output string format, we can build the interpreter as described on the following snippet:

<html>
<head>
<style>
.line {
    font-family: Verdana;
    font-size: 10px;
    font-color: Grey;
}
.paging {
    font-family: Verdana;
    font-size: 20px;
    font-color: Orange;
    width: 50ps;
    background-color: Grey;
    border-color: Black;
    border-style: solid;
    border-width: 1ps;
}
.current_page {
    font-family: Verdana;
    font-size: 18px;
    font-color: Black;
}
.box {
    border-bottom-color: Grey;
    border-bottom-width: 1px;
    border-bottom-style: solid;
    width: 100%;
}
</style>
</head>
<body>
<div>
<p>TEST</p>
<?php

//html vars
//paging
$page = "1";
if($_GET["page"]){
        $page = $_GET["page"];
}
//paging
//html vars
//vars
$holder = "";
$left = "";
$right = "";
//vars

// Include Composer Autoloader
$loader = require_once(__DIR__ . "/../vendor/autoload.php");

$api = new MaxCDN("ALIAS", "KEY", "SECRET");
try {

$prev = "";
$next = "";
$params = array("start"=>"2015-07-15 00:00:00", "end"=>"2015-07-16 00:00:00", "limit"=>"10", "page"=>"$page");
$res = $api->get('/v3/reporting/logs.json', $params);
$dat = json_decode($res, true);

foreach($dat['records'] as $record){
        $left .= "<p class='line'>Hostname: " . $record['hostname'] . "</p>
        <p class='line'>Uri: " . $record['uri'] . "</p>
        <p class='line'>Query String: " . $record['query_string'] . "</p>
        <p class='line'>Cache Status: " . $record['cache_status'] . "</p>
        <p class='line'>Visitor IP: " . $record['client_ip'] . "</p>
        <p class='line'>Visitor Latitude: " . $record['client_latitude'] . "</p>
        <p class='line'>Visitor Longitude: " . $record['client_longitude'] . "</p>
        <p class='line'>CDN PoP: " . $record['pop'] . "</p>
        <p class='line'>Visitor ASN: " . $record['client_asn'] . "</p>
        <p class='line'>Bytes Delivered: " . $record['bytes'] . "</p>
        <p class='line'>User Agent: " . $record['user_agent'] . "</p>
        <p class='line'>Referrer: " . $record['referer'] . "</p>
        <p class='line'>Request Method: " . $record['method'] . "</p><div class='box'></div>";
}
$page = $dat['page'];
if($dat['next_page_key'] != Null){
        $next = '<a class="paging" href="?page=' . ++$page . '">FWD</a>';
}

if($dat['page'] > 1){
        $prev = '<a class="paging" href="?page=' . --$dat['page'] . '">BACK</a>';
}

echo "<div align='center'><table><tr><td>" . $left . "</td></tr><tr><td>" . $right . "</td></tr></table>";

echo "<p class='current_page'>" . $prev . " Current Page: " . $_GET['page'] . " " . $next . " </p></div>";

} catch(CurlException $e) {
  print_r($e->getMessage());
  print_r($e->getHeaders());
}
?>

Example output:

If you have any questions about this custom interface for Raw Logs, please leave a comment below.