ns::stats::SQLiteHistory method history query (public)
<instance of ns::stats::SQLiteHistory> history query -from from \ -to to [ -server server ] [ -limit limit ] [ -cursor cursor ]
Return stored samples, associated topology, paging information and coverage for an epoch interval. Queries run in the configuring virtual server and use an operation-local database handle. Historical server selection may include servers no longer active.
- Switches:
- -from (required, integer)
- -to (required, integer)
- -server (optional)
- -limit (optional, integer, defaults to
"1000")- -cursor (optional, integer, defaults to
"0")- Testcases:
- No testcase defined.
Source code: if {$from < 0 || $to <= $from || $to - $from > 86400 || $to > [clock seconds] || $limit < 1 || $limit > 1000 || $cursor < 0 } { error "expected an epoch window up to 24 hours, limit 1..1000 and nonnegative cursor" } if {[string length $server]>512 || [string first \x00 $server] >= 0} { error "invalid server name" } set config [nsv_get ns_stats history] if {$config eq ""} { error "history is not configured" } if {[dict get $config owner] ne [ns_info server]} { error "query history from its configured owner server" } set db [:historyConnect $config] set transaction false try { ::ns::stats::sql $db {BEGIN} set transaction true set low [expr {$from * 1000000}] set high [expr {$to * 1000000}] set count [expr {$limit + 1}] set rows [::ns::stats::sql $db "SELECT at,topology,payload FROM ns_stats_samples WHERE at >= $low AND at < $high AND at > $cursor ORDER BY at LIMIT $count"] set more [expr {[llength $rows]>$limit}] set rows [lrange $rows 0 [expr {$limit - 1}]] set records {} set gaps {} set restarts {} set previous {} set topology {} set resets 0 set boundary [expr {max($low,$cursor)}] set operator [expr {$cursor >= $low ? "<=" : "<"}] set prior [::ns::stats::scalar $db "SELECT payload FROM ns_stats_samples WHERE at $operator $boundary ORDER BY at DESC LIMIT 1"] if {$prior ne ""} { set previous [::ns::stats::unpack $prior] } foreach row $rows { set record [::ns::stats::unpack [dict get $row payload]] if {![dict get $record sampling ready]} { incr resets } if {$previous ne ""} { if {[dict get $previous instance] ne [dict get $record instance]} { lappend restarts [dict get $record sampling to] } set delta [expr {([dict get $record timestamp]-[dict get $previous timestamp])/1000000.0}] if {$delta > 1.5 * max([dict get $previous sampling intervalSeconds],[dict get $record sampling intervalSeconds])} { lappend gaps [dict create from [dict get $previous sampling to] to [dict get $record sampling to]] } } set previous $record set id [dict get $row topology] dict set record topologyId $id if {![dict exists $topology $id]} { dict set topology $id [:selectServer [::ns::stats::unpack [::ns::stats::scalar $db "SELECT payload FROM ns_stats_topology WHERE id=[::ns::stats::quote $id]"]] $server false] } lappend records [:selectServer $record $server false] } if {!$more && $previous ne ""} { set following [::ns::stats::scalar $db "SELECT payload FROM ns_stats_samples WHERE at >= $high ORDER BY at LIMIT 1"] if {$following ne ""} { set nextRecord [::ns::stats::unpack $following] set delta [expr {([dict get $nextRecord timestamp]-[dict get $previous timestamp])/1000000.0}] if {$delta > 1.5 * max([dict get $previous sampling intervalSeconds],[dict get $nextRecord sampling intervalSeconds])} { lappend gaps [dict create from [dict get $previous sampling to] to [dict get $nextRecord sampling to]] } } } set bounds [lindex [::ns::stats::sql $db {SELECT coalesce(min(at),0) AS first,coalesce(max(at),0) AS last FROM ns_stats_samples}] 0] set events [::ns::stats::sql $db {SELECT at,first,last,n,reason FROM ns_stats_events ORDER BY id DESC}] set first [dict get $bounds first] set last [dict get $bounds last] set overlap false foreach event $events { if {[dict get $event first] < $high && [dict get $event last] >= $low} { set overlap true } } set through [::ns::stats::scalar $db {SELECT value FROM ns_stats_meta WHERE key='droppedThrough'}] if {$through ne "" && $through >= $low} { set overlap true } set next {} if {$more} { set next [dict get [lindex $rows end] at] } set complete [expr {$first > 0 && $first <= $low && $last >= $high && !$more && $cursor == 0 && !$overlap && $gaps eq "" && $restarts eq "" && $resets == 0}] set result [dict create schemaVersion 1 from $from to $to records $records topologies $topology nextCursor $next more $more coverage [dict create complete $complete windowExamined [expr {!$more && $cursor == 0}] retainedFrom [expr {$first / 1000000.0}] retainedTo [expr {$last / 1000000.0}] gaps $gaps restartBoundaries $restarts resetSamples $resets events $events evictionOrFailureOverlap $overlap droppedThrough $through writeFailuresSinceStart [dict get $config failures]]] ::ns::stats::sql $db {COMMIT} set transaction false return $result } finally { if {$transaction} { catch {::ns::stats::sql $db {ROLLBACK}} } ns_db releasehandle $db }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)