nsmcp::AccessRecordStoreSQLite method stats (public)

 <instance of nsmcp::AccessRecordStoreSQLite[i]> stats options \
    redactor limits

Defined in /usr/local/ns/tcl/nsmcp/log-traffic-record-store.tcl

Parameters:
options (required)
redactor (required)
limits (required)

Testcases:
No testcase defined.
Source code:
lassign [:filters $options] context selected
set from [dict get $options from]; set to [dict get $options to]
set stats [accessScanEmpty]
set row [lindex [${:db} execute "SELECT count(*) AS contextRecords,coalesce(sum(status>=400),0) AS contextFailedRecords FROM temp.nsmcp_record_window WHERE $context"] 0]
set stats [dict merge $stats $row]
set row [lindex [${:db} execute "SELECT count(*) AS requestCount,coalesce(sum(status<400),0) AS statusBelow400Records,coalesce(sum(bytes),0) AS responseBytes,
    coalesce(sum(phase),0) AS timingCount,coalesce(sum(fallback),0) AS fallbackCount,coalesce(sum(a),0) AS acceptTotal,coalesce(sum(q),0) AS queueTotal,
    coalesce(sum(f),0) AS filterTotal,coalesce(sum(r),0) AS runTotal,coalesce(max(r),0) AS runMax,coalesce(min(t),'') AS matchedFirstAt,coalesce(max(t),'') AS matchedLastAt,
    coalesce(sum(peer=''),0) AS unknownPeerRecords,coalesce(sum(agent=''),0) AS unknownUserAgentRecords,coalesce(sum(clipped),0) AS truncatedUserAgentRecords,
    coalesce(sum(source='driver' AND status=503),0) AS driver503Records FROM temp.nsmcp_record_window WHERE $selected"] 0]
set stats [dict merge $stats $row]
set row [lindex [${:db} execute {SELECT count(*) AS examinedRecords,coalesce(sum(kind=1),0) AS parseErrors,coalesce(sum(kind=2),0) AS oversizedRecords,coalesce(min(t),'') AS earliestAt,coalesce(max(t),'') AS latestAt FROM temp.nsmcp_record_window}] 0]
set stats [dict merge $stats $row]
dict set stats pendingRecords [:boundaryPending]
foreach {field column cap} [list paths path [dict get $limits keys] methods method 32 statuses status 500 pools pool 64 hours {CAST(t/3600 AS INTEGER)*3600} 170 drivers driver 64] {
    set where $selected
    if {$field eq "drivers"} {append where " AND source='driver'"}
    set known 0
    foreach row [${:db} execute "SELECT $column AS value,count(*) AS n FROM temp.nsmcp_record_window WHERE $where GROUP BY $column ORDER BY n DESC,value LIMIT $cap"] {
        set value [dict get $row value]; set n [dict get $row n]
        if {$field ni {hours statuses}} {set value [$redactor message $value]}
        if {$field eq "paths" && [string length [encoding convertto utf-8 $value]]>1024} continue
        set counts [dict get $stats $field]; dict incr counts $value $n; dict set stats $field $counts; incr known $n
    }
    set total [${:db} scalar "SELECT count(*) FROM temp.nsmcp_record_window WHERE $where"]
    if {$known<$total} {dict set stats omittedRecords $field [expr {$total-$known}]}
}
foreach {field column} {authenticationStates auth recordSources source} {
    foreach row [${:db} execute "SELECT $column AS value,count(*) AS n FROM temp.nsmcp_record_window WHERE $selected GROUP BY $column"] {dict set stats $field [dict get $row value] [dict get $row n]}
}
foreach row [${:db} execute "SELECT status,count(*) AS requestCount,sum(phase) AS timingCount,sum(r) AS runTotal,max(r) AS runMax FROM temp.nsmcp_record_window WHERE $selected GROUP BY status"] {
    set status [dict get $row status]; dict unset row status; dict set stats statusTimings $status $row
}
set seconds [dict get $options bucketSeconds]; set index "CAST((t-[${:db} quote $from])/$seconds AS INTEGER)"
foreach row [${:db} execute "SELECT $index AS i,count(*) AS n,sum(status>=400) AS failed,sum(phase) AS timings,sum(r) AS runtime FROM temp.nsmcp_record_window WHERE $context GROUP BY i LIMIT 3600"] {
    dict set stats buckets [dict get $row i] [list contextRecords [dict get $row n] contextFailedRecords [dict get $row failed] selectedRecords 0 driver503Records 0 timingCount 0 runTotal 0.0 contextTimingCount [dict get $row timings] contextRunTotal [dict get $row runtime]]
}
foreach row [${:db} execute "SELECT $index AS i,count(*) AS n,sum(source='driver' AND status=503) AS driver503,sum(phase) AS timings,sum(r) AS runtime FROM temp.nsmcp_record_window WHERE $selected GROUP BY i LIMIT 3600"] {
    set i [dict get $row i]
    foreach {key col} {selectedRecords n driver503Records driver503 timingCount timings runTotal runtime} {dict set stats buckets $i $key [dict get $row $col]}
}
set aggregate [dict create backend sqlite cacheKiB 8192 status active reason {} maxBytes [dict get ${:settings} maxBytes] diskBytes [:diskBytes] peakBufferedKeys 512 peerOmitted 0 agentOmitted 0 labelTruncatedRecords 0 labelRedactedRecords 0]
foreach {field col} {peers peer agents agent} {
    set valid "$selected AND $col<>''"
    set totals [dict create distinct [${:db} scalar "SELECT count(DISTINCT $col) FROM temp.nsmcp_record_window WHERE $valid"] records [${:db} scalar "SELECT count(*) FROM temp.nsmcp_record_window WHERE $valid"] top1 0 top10 0 top100 0 rankedRecords 0 clippedRecords 0 redactedRecords 0]
    set entries {}; set i 0
    foreach row [${:db} execute "SELECT hex($col) AS k,count(*) AS n,min(label) AS label,max(clipped) AS clipped,max(redacted) AS redacted FROM temp.nsmcp_record_window WHERE $valid GROUP BY $col ORDER BY n DESC,k LIMIT 100"] {
        incr i; set n [dict get $row n]
        if {$i==1} {dict set totals top1 $n}; if {$i<=10} {dict incr totals top10 $n}; dict incr totals top100 $n
        if {$i<=[dict get $options maxGroups]} {
            dict incr totals rankedRecords $n
            lappend entries [dict create count $n value [dict get $row label] valueTruncated [dict get $row clipped] valueRedacted [dict get $row redacted]]
        }
    }
    dict set aggregate $field $entries; dict set aggregate ${field}Totals $totals
}
set last [${:db} scalar "SELECT coalesce(sum(clipped),0) FROM temp.nsmcp_record_window WHERE $selected"]
dict set aggregate labelTruncatedRecords $last
dict set aggregate labelRedactedRecords [${:db} scalar "SELECT coalesce(sum(redacted),0) FROM temp.nsmcp_record_window WHERE $selected"]
return [list $stats $aggregate $selected]
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: