{% if log_stats.files_found != 1 %}{{ log_stats.files_ok }}/{{ log_stats.files_found }} files · {% endif %}{{ log_label }} · {{ log_size }} {{ s.first_ts }} → {{ s.last_ts }} {{ s.span_hours }}h window {% if log_stats.files_error %}{{ log_stats.files_error }} file errors{% endif %} {% if s.emby_api_enabled %}Emby API connected{% endif %}
Refresh
Total Requests
{{ "{:,}".format(s.total) }}
{{ s.span_hours }}h window
Blocked (403)
{{ "{:,}".format(s.blocked_403_total) }}
{{ "%.1f"|format(s.blocked_403_total / s.total * 100 if s.total else 0) }}% of traffic
Server Errors
{{ "{:,}".format(s.errors_5xx_total) }}
5xx responses
Slow Requests
{{ "{:,}".format(s.slow_total) }}
≥ 2 second latency
Unique IPs
{{ "{:,}".format(s.by_ip|length) }}
distinct sources
Emby Devices
{{ "{:,}".format(s.device_registry|length) }}
tracked by device ID
Traffic
Status Distribution
{% set ns = namespace(tot=0) %} {% for k,v in s.by_status_class.items() %}{% set ns.tot = ns.tot + v %}{% endfor %}
{% for klass, count in s.by_status_class.items() %} {% set pct = (count / ns.tot * 100)|round(1) if ns.tot else 0 %} {% if klass=='2xx' %}{% set col='var(--good)' %} {% elif klass=='3xx' %}{% set col='var(--accent)' %} {% elif klass=='4xx' %}{% set col='var(--warn)' %} {% elif klass=='5xx' %}{% set col='var(--bad)' %} {% else %}{% set col='var(--muted)' %}{% endif %}
{% endfor %}
{% for klass, count in s.by_status_class.items() %} {% set pct = (count / ns.tot * 100)|round(1) if ns.tot else 0 %} {% endfor %}
ClassCountShare
{{ klass }} {{ "{:,}".format(count) }} {{ pct }}%
Top Source IPs {{ s.by_ip|length }} unique
{% set max_ip = s.by_ip[0][1] if s.by_ip else 1 %} {% for ip, count in s.by_ip[:15] %}
{{ ip }}
{{ "{:,}".format(count) }}
{% endfor %}
Per-Host Traffic {{ s.by_host|length }} hosts
{% for h in s.by_host %}
{{ h.host }}
{{ "{:,}".format(h.hits) }} {{ h.bytes_human }}
{% for klass, count in h.status_mix.items() %} {{ klass }}:{{ count }} {% endfor %}
{% endfor %}
Emby Intelligence {{ s.device_registry|length }} devices · {{ s.emby_clients|length }} clients
{% if s.device_registry %}
Device Registry identified by DeviceId{% if s.emby_api_enabled %} · usernames via Emby API{% endif %}
{% for dev in s.device_registry %} {% set cl = (dev.client or '')|lower %} {% if 'fire' in cl or 'amazon' in cl %} {% set ico='🔥' %}{% set ibg='rgba(245,166,35,0.12)' %} {% elif 'ios' in cl or 'iphone' in cl or 'ipad' in cl %} {% set ico='📱' %}{% set ibg='rgba(56,192,248,0.12)' %} {% elif 'android' in cl %} {% set ico='📱' %}{% set ibg='rgba(77,142,245,0.14)' %} {% elif 'web' in cl or 'browser' in cl %} {% set ico='🌐' %}{% set ibg='rgba(124,90,245,0.12)' %} {% elif 'tv' in cl or 'roku' in cl or 'bravia' in (dev.device or '')|lower %} {% set ico='📺' %}{% set ibg='rgba(16,211,160,0.12)' %} {% elif 'windows' in cl or 'desktop' in cl %} {% set ico='🖥️' %}{% set ibg='rgba(245,166,35,0.12)' %} {% else %} {% set ico='📡' %}{% set ibg='rgba(255,255,255,0.05)' %} {% endif %}
{{ ico }}
{{ dev.device or 'Unknown Device' }}
{{ dev.client or 'Unknown Client' }}
{% if dev.version %}v{{ dev.version }}{% endif %} {% if dev.username %} 👤 {{ dev.username }} {% endif %} {{ "{:,}".format(dev.hits) }} req
{% if dev.ips %}
{% for ip in dev.ips[:4] %}{{ ip }}{% endfor %} {% if dev.ips|length > 4 %}+{{ dev.ips|length - 4 }}{% endif %}
{% endif %}
{{ dev.device_id[:16] }}… {{ dev.last_seen }}
{% endfor %}
{% endif %}
Client Applications
{% if s.emby_breakdown %} {% for b in s.emby_breakdown %}
{{ b.client }} {{ "{:,}".format(b.total) }}
{% for ver, count in b.versions.items() %} {{ ver }}: {{ count }} {% endfor %}
{% endfor %} {% else %}
📡
No Emby client data in this window.
{% endif %}
Device Names
{% if s.emby_devices %} {% set max_d = s.emby_devices[0][1] %} {% for d, count in s.emby_devices[:20] %}
{{ d }}
{{ "{:,}".format(count) }}
{% endfor %} {% else %}
🔍
No device data found.
{% endif %}
Security {{ s.blocked_403_total }} blocked
Block Trigger Analysis
{% if s.blocked_403_by_trigger %} {% set max_t = s.blocked_403_by_trigger[0][1] %} {% for trigger, count in s.blocked_403_by_trigger %}
{{ trigger }}
{{ count }}
{% endfor %} {% else %}
No triggers identified.
{% endif %}
Top Blocked IPs
{% if s.blocked_ips_top %} {% set max_bi = s.blocked_ips_top[0][1] %} {% for ip, count in s.blocked_ips_top %}
{{ ip }}
{{ count }}
{% endfor %} {% else %}
No blocked IPs.
{% endif %}
Recent 403 Blocks {{ s.blocked_403_total }} total · showing {{ [s.blocked_403|length, 30]|min }}
{% for e in s.blocked_403[:30] %} {% set mcls = 'm' + e.method if e.method in ['GET','POST','PUT','DELETE'] else 'mOTHER' %} {% endfor %}
TimeHostMethodURI Emby IdentityIPUser-Agent
{{ e.time }} {{ e.host }} {{ e.method }} {{ e.uri }} {% if e.emby_client or e.emby_device %}
{% if e.emby_client %}
{{ e.emby_client }}
{% endif %} {% if e.emby_device %}
{{ e.emby_device }}
{% endif %} {% if e.emby_version %}v{{ e.emby_version }}{% endif %} {% if e.emby_device_id %} {{ e.emby_device_id[:8] }}…{% endif %}
{% else %}{% endif %}
{{ e.ip }} {{ e.ua }}
Errors & Performance
Server Errors (5xx) {{ s.errors_5xx_total }} total
{% if s.errors_5xx_total == 0 %}
No server errors in this window.
{% else %}
{% for e in s.errors_5xx[:20] %} {% endfor %}
TimeHostURIStatus
{{ e.time }} {{ e.host }} {{ e.uri }} {{ e.status }}
{% endif %}
Slow Requests (≥ 2s) {{ s.slow_total }} total
{% if s.slow_total == 0 %}
Everything's snappy.
{% else %}
{% for e in s.slow_requests[:20] %} {% endfor %}
TimeHostURIDuration
{{ e.time }} {{ e.host }} {{ e.uri }} {{ e.duration }}s
{% endif %}
Auth Service {{ s.auth_summary.total }} events
{% if s.auth_summary.total == 0 %}
🔒
No auth events in this log window.
{% else %}
By Path
{% set max_ap = s.auth_summary.by_path[0][1] if s.auth_summary.by_path else 1 %} {% for path, count in s.auth_summary.by_path %}
{{ path }}
{{ count }}
{% endfor %}
By Source IP
{% set max_aip = s.auth_summary.by_ip[0][1] if s.auth_summary.by_ip else 1 %} {% for ip, count in s.auth_summary.by_ip %}
{{ ip }}
{{ count }}
{% endfor %}
Recent Auth Requests
{% for e in s.auth_summary.recent %} {% set mcls = 'm' + e.method if e.method in ['GET','POST','PUT','DELETE'] else 'mOTHER' %} {% set scls = 'c' + (e.status // 100)|string %} {% endfor %}
TimeMethodPathStatusIP
{{ e.time }} {{ e.method }} {{ e.uri }} {{ e.status }} {{ e.ip }}
{% endif %}