%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/old/opt/luameter/
Upload File :
Create Path :
Current File : //data/old/opt/luameter/index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Nginx Stats - by Luameter</title>
    <link rel="stylesheet" href="vendor/tables-min.css">
    <style>
        h1, h2, h3, h4, h5 {
            font-weight: 400;
        }
        h3 {
            font-style: italic;
        }
        html {
            font-family: sans-serif;
            font-size: 13px;
            color: rgb(75, 75, 75);
        }
        a {
            color: rgb(75, 75, 75);
            text-decoration: none;
        }
        .main {
            padding: 20px;
        }
        .sub-head {
            font-size: 50%;
            color: #777;
        }
        .tooltip {
            text-align: left;
            border-bottom: 1px #999 dotted;
            display: inline;
            position: relative;
            cursor: help;
        }
        .tooltip:hover:after {
            background: #4b4b4b;
            bottom: 26px;
            color: #fff;
            content: attr(title);
            left: 20%;
            padding: 5px 15px;
            position: absolute;
            z-index: 98;
            width: 10em;
            white-space: pre-line;
        }
        .tooltip:hover:before {
            border: solid;
            border-color: #4b4b4b transparent;
            border-width: 6px 6px 0 6px;
            bottom: 20px;
            content: "";
            left: 50%;
            position: absolute;
            z-index: 99;
        }
    </style>
</head>
<body>
<div class="main">
    <div id="stats">
        <h1><a href="http://luameter.com">Luameter<a></h1>
    </div>
</div>

<script id="stats-template" type="text/x-handlebars-template">
    <h1><a href="http://luameter.com">Luameter</a> <span class="sub-head">{{ luameter_version }}</span></h1>
    <h2>Server</h2>
    <table class="pure-table">
        <thead>
        <tr>
            <th rowspan="2">Nginx</th>
            <th rowspan="2">Ngx_lua</th>
            <th rowspan="2">Uptime</th>
            <!--<th>Timestamp</th>-->
            <th colspan="4">Connections</th>
        </tr>
        <tr>
            <th>Active</th>
            <th>Reading</th>
            <th>Writing</th>
            <th>Waiting</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>{{ nginx_version }}</td>
            <td>{{ ngx_lua_version }}</td>
            <td>{{ uptime uptime }}</td>
            <!--<td>{{ timestamp }}</td>-->
            <td>{{ connections.active }}</td>
            <td>{{ connections.reading }}</td>
            <td>{{ connections.writing }}</td>
            <td>{{ connections.waiting }}</td>
        </tr>
        </tbody>
    </table>
    <h2>Zone</h2>
    <table class="pure-table pure-table-striped">
        <thead>
        <tr>
            <th rowspan="2">Zone</th>
            <th colspan="3">Requests</th>
            <th colspan="6">Responses</th>
            <th colspan="3">Latency (ms)</th>
            <th colspan="2">Traffic</th>
            <th colspan="3">Cache</th>
        </tr>
        <tr>
            <th>Rate (r/s)</th>
            <th>Moving Avg (r/s)</th>
            <th>Total</th>

            <th>1xx</th>
            <th>2xx</th>
            <th>3xx</th>
            <th>4xx</th>
            <th>5xx</th>
            <th>Total</th>

            <th>Mean</th>
            <th>P90</th>
            <th>P99</th>

            <th>Received</th>
            <th>Sent</th>

            <th>Hit</th>
            <th>Miss</th>
            <th>Expired</th>
        </tr>
        </thead>
        <tbody>
        {{#each_in_order zones}}{{#with this}}
        <tr>
            <td>{{ name }}</td>

            <td>
                <span class="line">{{ requests_per_sec_history }}</span>
                &nbsp;
                {{ round requests_per_sec 0 }}
            </td>
            <td>
                <span class="bar">
                    {{ round rates.one_minute_avg }},
                    {{ round rates.five_minute_avg }},
                    {{ round rates.fifteen_minute_avg}}
                </span>
                &nbsp;
                {{ round rates.one_minute_avg }}
                &middot;
                {{ round rates.five_minute_avg }}
                &middot;
                {{ round rates.fifteen_minute_avg }}
            </td>
            <td>{{ requests }}</td>

            <td>
                <a class="tooltip" title="{{ responses.[1xx_details] }}">
                    {{ responses.[1xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[2xx_details] }}">
                    {{ responses.[2xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[3xx_details] }}">
                    {{ responses.[3xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[4xx_details] }}">
                    {{ responses.[4xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[5xx_details] }}">
                    {{ responses.[5xx] }}
                </a>
            </td>
            <td>
                {{ responses.total }}
            </td>

            <td>{{ round latency.mean 1 }}</td>
            <td>{{ round latency.p90 1 }}</td>
            <td>{{ round latency.p99 1 }}</td>

            <td>
                <a class="tooltip" title="Total: {{ bytes received }}">
                    {{ bytes received_per_sec }}/s
                </a>
            </td>
            <td>
                <a class="tooltip" title="Total: {{ bytes sent }}">
                    {{ bytes sent_per_sec }}/s
                </a>
            </td>

            <td>
                <a class="tooltip" title="Hit Ratio: {{ round cache.hit_ratio }}">
                    {{ cache.hit }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="Miss Ratio: {{ round cache.miss_ratio }}">
                    {{ cache.miss }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="Expired Ratio: {{ round cache.expired_ratio }}">
                    {{ cache.expired }}
                </a>
            </td>
        </tr>
        {{/with}}{{/each_in_order}}
        </tbody>
    </table>
    <h2>Upstream</h2>
    <table class="pure-table pure-table-stripped">
        <thead>
        <tr>
            <th rowspan="2">Upstream</th>
            <th colspan="3">Requests</th>
            <th colspan="6">Responses</th>
            <th colspan="3">Latency (ms)</th>
            <th colspan="2">Traffic</th>
        </tr>
        <tr>
            <th>Rate (r/s)</th>
            <th>Moving Avg</th>
            <th>Total</th>

            <th>1xx</th>
            <th>2xx</th>
            <th>3xx</th>
            <th>4xx</th>
            <th>5xx</th>
            <th>Total</th>

            <th>Mean</th>
            <th>P90</th>
            <th>P99</th>

            <th>Received</th>
            <th>Sent</th>
        </tr>
        </thead>
        <tbody>
        {{#each_in_order upstreams}}{{#with this}}
        <tr>
            <td>{{ name }}</td>

            <td>
                <span class="line">{{ requests_per_sec_history }}</span>
                &nbsp;
                {{ round requests_per_sec 0 }}
            </td>
            <td>
                <span class="bar">
                    {{ round rates.one_minute_avg }},
                    {{ round rates.five_minute_avg }},
                    {{ round rates.fifteen_minute_avg}}
                </span>
                &nbsp;
                {{ round rates.one_minute_avg }}
                &middot;
                {{ round rates.five_minute_avg }}
                &middot;
                {{ round rates.fifteen_minute_avg }}
            </td>
            <td>{{ requests }}</td>

            <td>
                <a class="tooltip" title="{{ responses.[1xx_details] }}">
                    {{ responses.[1xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[2xx_details] }}">
                    {{ responses.[2xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[3xx_details] }}">
                    {{ responses.[3xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[4xx_details] }}">
                    {{ responses.[4xx] }}
                </a>
            </td>
            <td>
                <a class="tooltip" title="{{ responses.[5xx_details] }}">
                    {{ responses.[5xx] }}
                </a>
            </td>
            <td>
                {{ responses.total }}
            </td>

            <td>{{ round latency.mean 1 }}</td>
            <td>{{ round latency.p90 1 }}</td>
            <td>{{ round latency.p99 1 }}</td>

            <td>
                <a class="tooltip" title="Total: {{ bytes received }}">
                    {{ bytes received_per_sec }}/s
                </a>
            </td>
            <td>
                <a class="tooltip" title="Total: {{ bytes sent }}">
                    {{ bytes sent_per_sec }}/s
                </a>
            </td>
        </tr>
        {{/with}}{{/each_in_order}}
        </tbody>
    </table>
</script>

<script src="vendor/jquery.min.js"></script>
<script src="vendor/handlebars.min.js"></script>
<script src="vendor/jquery.peity.min.js"></script>
<script>
MAX_HISTORY = 60;

var all_stats = {};
var charts = {};

Handlebars.registerHelper('uptime', function(seconds) {
    var days = seconds > 86400 ? Math.floor(seconds / 86400) + 'd ' : '';
    var hours = seconds > 3600 ? Math.floor(seconds % 86400 / 3600) + 'h ' : '';
    var minutes = seconds > 60 ? Math.floor(seconds % 3600 / 60) + 'm ' : '';
    seconds = Math.floor(seconds % 60) + 's';
    return days + hours + minutes + seconds;
});

Handlebars.registerHelper('each_in_order', function(context, options) {
    var ret = "";
    $.each(Object.keys(context).sort(), function(_, key) {
        var ctx = context[key];
        ctx['name'] = key;
        ret = ret + options.fn(ctx);
    });
    return ret;
});

var round = function(num, decimals) {
    num = num || 0;
    decimals = parseInt(decimals);
    if (isNaN(decimals)) {
        decimals = 2;
        if (num > 10) decimals = 1;
        if (num > 100) decimals = 0;
    }
    return parseFloat(num).toFixed(decimals);
};
Handlebars.registerHelper('round', round);

Handlebars.registerHelper('bytes', function(bytes) {
    if (!bytes) return '0 B';

    if (bytes < 1024) return round(bytes, 0) + ' B';

    var ki_bytes = round(bytes / 1024, 2);
    if (ki_bytes < 1024) return ki_bytes + ' KiB';

    var mi_bytes = round(ki_bytes / 1024, 2);
    if (mi_bytes < 1024) return mi_bytes + ' MiB';

    var gi_bytes = round(mi_bytes / 1024, 2);
    if (gi_bytes < 1024) return gi_bytes + ' GiB';

    var ti_bytes = round(gi_bytes / 1024, 2);
    return ti_bytes + ' TiB';
});

var calc_data_rate = function(name, stats) {
    var previous = all_stats[name];
    if (previous == undefined) return;

    var elapsed = stats.ts - previous.ts;
    $.each(['requests', 'received', 'sent'], function(_, key) {
        var diff = stats[key] - previous[key];
        if (elapsed > 0) {
            diff = diff / elapsed;
        }
        stats[key + '_per_sec'] = diff > 0 ? diff : 0;
    });

    $.each(['requests_per_sec'], function(_, key) {
        var history = stats[key + '_history'] = previous[key + '_history'];
        if (history == undefined) {
            history = stats[key + '_history'] = [];
        }
        var len = history.push(stats[key]);
        if (len > MAX_HISTORY) {
            history.shift();
        }
    });
};

var calc_cache_ratio = function(stats) {
    var total = stats['responses']['total'];
    if (total > 0) {
        $.each(['hit', 'miss', 'expired'], function (_, key) {
            stats['cache'][key + '_ratio'] = stats['cache'][key] / total;
        });
    }
};

var template = Handlebars.compile($('#stats-template').html());

var update = function() {
    $.getJSON('/stats', function(data) {
        var calc_derived_stats = function(name, stats) {
            stats.ts = data.timestamp;
            calc_data_rate(name, stats);
            calc_cache_ratio(stats);
            for (var i = 1; i <= 5; i++) {
                var statuses = [];
                for (var j = 0; j < 100; j++) {
                    var status = 100 * i + j;
                    if (stats.responses[status] > 0) {
                        statuses.push(status + ': ' + stats.responses[status]);
                    }
                }
                if (statuses.length == 0) {
                    stats.responses[i + 'xx_details'] = '0';
                } else {
                    stats.responses[i + 'xx_details'] = statuses.join('\x0A');
                }
            }
            all_stats[name] = stats;
        };
        $.each(data.zones, calc_derived_stats);
        $.each(data.upstreams, calc_derived_stats);

        // update stats table
        $('#stats').html(template(data));
        $('.line').peity('line', {width: MAX_HISTORY, fill: '#e0e0e0', stroke: '#4b4b4b'});
        $('.bar').peity('bar', {width: 18, fill: ['#6b6b6b']});
    });
};

update();
setInterval(update, 10000);
</script>
</body>
</html>

Zerion Mini Shell 1.0