mini-apm-admin 0.0.0

Minimal APM for Rails - Admin web interface
Documentation
{% extends "layout.html" %}

{% block title %}Routes - MiniAPM{% endblock %}

{% block project_selector %}
{% if ctx.show_selector() %}
<form method="POST" action="/projects/switch" class="project-selector">
    <select name="slug" onchange="this.form.submit()">
        {% for project in ctx.projects %}
        <option value="{{ project.slug }}" {% if ctx.is_current_project(project.id) %}selected{% endif %}>
            {{ project.name }}
        </option>
        {% endfor %}
    </select>
</form>
{% endif %}
{% endblock %}

{% block content %}
<h1>Routes</h1>
<p class="subtitle">{{ total_count }} route{% if total_count != 1 %}s{% endif %} found</p>

<div class="filter-bar">
    <div class="filter-group">
        <label>Period</label>
        <div class="filters">
            <a href="?period=1h&sort={{ sort }}{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if period == "1h" %}active{% endif %}">1h</a>
            <a href="?period=24h&sort={{ sort }}{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if period == "24h" %}active{% endif %}">24h</a>
            <a href="?period=7d&sort={{ sort }}{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if period == "7d" %}active{% endif %}">7d</a>
            <a href="?period=30d&sort={{ sort }}{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if period == "30d" %}active{% endif %}">30d</a>
        </div>
    </div>

    <div class="filter-group">
        <label>Sort by</label>
        <div class="filters">
            <a href="?period={{ period }}&sort=requests{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "requests" %}active{% endif %}">Requests</a>
            <a href="?period={{ period }}&sort=avg{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "avg" %}active{% endif %}">Avg</a>
            <a href="?period={{ period }}&sort=p95{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "p95" %}active{% endif %}">p95</a>
            <a href="?period={{ period }}&sort=p99{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "p99" %}active{% endif %}">p99</a>
            <a href="?period={{ period }}&sort=max{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "max" %}active{% endif %}">Max</a>
            <a href="?period={{ period }}&sort=db{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "db" %}active{% endif %}">DB</a>
            <a href="?period={{ period }}&sort=errors{% if let Some(s) = search %}&search={{ s }}{% endif %}" class="{% if sort == "errors" %}active{% endif %}">Errors</a>
        </div>
    </div>

    <div class="filter-group filter-search">
        <label>Search</label>
        <form method="GET" action="/performance" class="search-form">
            <input type="hidden" name="period" value="{{ period }}">
            <input type="hidden" name="sort" value="{{ sort }}">
            <input type="text" name="search" placeholder="Path..." value="{% if let Some(s) = search %}{{ s }}{% endif %}">
            <button type="submit">Search</button>
        </form>
    </div>
</div>

{% if routes.is_empty() %}
<p class="empty">No data for this period</p>
{% else %}
<div class="routes-table routes-table-wide">
    <div class="routes-header">
        <div class="col-route">Route</div>
        <div class="col-requests">Requests</div>
        <div class="col-timing">Avg</div>
        <div class="col-timing">p95</div>
        <div class="col-timing">p99</div>
        <div class="col-timing">Max</div>
        <div class="col-db">DB</div>
        <div class="col-errors">Errors</div>
    </div>
    {% for route in routes %}
    <div class="routes-row">
        <div class="col-route">
            <span class="method method-{{ route.method }}">{{ route.method }}</span>
            <a href="/traces?search={{ route.path }}" class="path">{{ route.path }}</a>
        </div>
        <div class="col-requests">
            <div class="bar-container">
                <div class="bar bar-requests" style="width: {{ (route.request_count * 100 / max_requests) }}%;"></div>
            </div>
            <span class="value">{{ route.request_count }}</span>
        </div>
        <div class="col-timing">
            <span class="timing-avg {% if route.avg_ms > 500 %}timing-slow{% else if route.avg_ms > 200 %}timing-medium{% endif %}">{{ route.avg_ms }}ms</span>
        </div>
        <div class="col-timing">
            <span class="timing-p95 {% if route.p95_ms > 500 %}timing-slow{% else if route.p95_ms > 200 %}timing-medium{% endif %}">{{ route.p95_ms }}ms</span>
        </div>
        <div class="col-timing">
            <span class="timing-p99 {% if route.p99_ms > 500 %}timing-slow{% else if route.p99_ms > 200 %}timing-medium{% endif %}">{{ route.p99_ms }}ms</span>
        </div>
        <div class="col-timing">
            <span class="timing-max">{{ route.max_ms }}ms</span>
        </div>
        <div class="col-db">
            <span class="db-time">{{ route.avg_db_ms }}ms</span>
            <span class="db-queries">({{ route.avg_db_count }})</span>
        </div>
        <div class="col-errors">
            {% if route.error_count > 0 %}
            <span class="error-badge">{{ route.error_count }}</span>
            <span class="error-rate">({{ "{:.1}"|format(route.error_rate) }}%)</span>
            {% else %}
            <span class="no-errors">-</span>
            {% endif %}
        </div>
    </div>
    {% endfor %}
</div>
{% endif %}
{% endblock %}