Class ::nsmcp::UnifiedAccessAnalytics

::nsmcp::UnifiedAccessAnalytics[i] create ... \
           [ -database:required database:required ] \
           [ -evictionLimit:integer (default "64") ] \
           [ -ingestBytes:integer (default "16777216") ] \
           [ -ingestMilliseconds:integer (default "2000") ] \
           [ -legacyDatabase (default "") ] \
           [ -maxLineBytes:integer (default "65536") ] \
           [ -maxReadBytes:integer (default "16777216") ] \
           [ -maxRows:integer (default "2000000") ] \
           [ -maxSeconds:integer (default "2") ] \
           [ -mutex (default "") ] \
           [ -parser (default "::nsmcp::accessRecordParser") ] \
           [ -path:required path:required ] \
           [ -retentionBatchRows:integer (default "1000") ] \
           [ -retentionInterval (default "30") ] \
           [ -retentionMilliseconds:integer (default "1000") ] \
           [ -retentionSeconds:double (default "86400") ] \
           [ -settings:required settings:required ] \
           [ -sourceReady (default "false") ]

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

Class Relations

  • class: ::nx::Class[i]
  • superclass: ::nsmcp::AccessAnalytics[i]
::nx::Class create ::nsmcp::UnifiedAccessAnalytics \
     -superclass ::nsmcp::AccessAnalytics

Methods (to be applied on instances)

  • correlateWarnings (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> correlateWarnings \
        samples redactor

    Correlate warnings with unified stored requests. Delegate through bounded store retry while preserving the caller's sample list and redactor.

    Parameters:
    samples (required)
    Bounded warning sample records to correlate with retained access evidence.
    redactor (required)
    Redactor object applied before returning diagnostic evidence.
    Returns:
    The warning correlation evidence.

    Testcases:
    No testcase defined.
    return [:accessRecordRetry ${:settings} [list next [list $samples $redactor]]]
  • ingest (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> ingest [ from ] \
        [ allowHistory ]

    Provide the compatibility entry point for an administrative refresh. Legacy range arguments remain accepted; the unified ingestor controls its live and historical work through refresh.

    Parameters:
    from (optional)
    Starting timestamp or byte position, as required by the operation.
    allowHistory (optional, defaults to "true")
    Whether this pass may process historical sources. Defaults to 'true'.
    Returns:
    The bounded refresh result.

    Testcases:
    No testcase defined.
    # Compatibility entry point for explicit administrative refreshes only.
    return [:refresh]
  • ingestionStatus (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> ingestionStatus

    Read current and last-run ingestion progress. Use the retained ingestion status instead of triggering a scan or ingestion pass.

    Returns:
    The ingestion status dictionary.

    Testcases:
    No testcase defined.
    return [accessIngestionStatus]
  • refresh (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> refresh

    Run a bounded unified ingestion pass under the writer gate. Reject overlapping writers, publish phase and commit statistics, and always finish the run token before releasing the gate.

    Returns:
    The ingestion result, or a busy dictionary when another writer owns the gate.

    Testcases:
    No testcase defined.
    set gate nsmcp:unified-writer:[ns_info server]
    if {[nsv_incr $gate busy]!=1} {
        nsv_incr $gate busy -1
        return {busy true}
    }
    set run {}
    set outcome error
    set result {}
    try {
        set run [accessIngestionBegin]
        set result [:accessRecordRetry ${:settings} [list :refreshLocked $run] {} [list ::nsmcp::accessIngestionProgress $run retry]]
        set outcome [expr {[dict exists $result busy] ? "pool-busy" : "ok"}]
        if {![dict exists $result busy]} {
            nsv_unset -nocomplain nsmcp:access-store:[ns_info server] lastFailure
        }
        return $result
    } on error {message options} {
        set result [accessUnifiedFailure ${:settings} $options]
        return $result
    } finally {
        try {
            accessIngestionFinish $run $outcome $result
        } finally {
            nsv_incr $gate busy -1
        }
    }
  • retain (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> retain

    Perform bounded retention maintenance under the writer gate. Avoid overlapping ingestion while pruning expired store state and retaining maintenance statistics.

    Returns:
    The retention result, including a busy indication when the gate is occupied.

    Testcases:
    No testcase defined.
    # Share the writer gate: maintenance never overlaps ingestion and never
    # waits for a running importer. Readers retain their WAL snapshots.
    set gate nsmcp:unified-writer:[ns_info server]
    if {[nsv_incr $gate busy]!=1} {
        nsv_incr $gate busy -1
        return {busy true}
    }
    set key nsmcp:access-retention:[ns_info server]
    set token [nsv_incr $key sequence]
    set began [clock clicks -milliseconds]
    set store {}
    set outcome error
    set counts {requests 0 diagnostics 0 minutes 0 peers 0}
    set batches 0
    set code {}
    set last [expr {[nsv_exists $key state] ? [dict get [nsv_get $key state] lastRun] : {}}]
    nsv_set $key state [dict create token $token running true startedAt [clock seconds] startedTicks $began phaseTicks $began phase open-store deleted $counts lastRun $last]
    try {
        set store [:accessRecordStoreOpen ${:settings} writer [list ::nsmcp::accessRetentionPhase $token]]
        if {![$store available]} {
            set outcome pool-busy
            return {busy true}
        }
        while {$batches==0 || [clock clicks -milliseconds]-$began<${:retentionMilliseconds}} {
            accessRetentionPhase $token prune
            set removed [$store prune ${:retentionBatchRows}]
            incr batches
            set total 0
            dict for {table n} $removed {
                dict incr counts $table $n
                incr total $n
            }
            set state [nsv_get $key state]
            dict set state deleted $counts
            nsv_set $key state $state
            if {$total==0} {
                break
            }
        }
        set outcome ok
        return [dict create deleted $counts batches $batches]
    } on error {message options} {
        set code {NSMCP RETENTION operation-failed}
        set candidate [dict get $options -errorcode]
        if {[lrange $candidate 0 1] eq {NSMCP RECORD_STORE} && [regexp {^[a-z][a-z0-9-]{0,63}$} [lindex $candidate 2]]} {
            set code [lrange $candidate 0 2]
        }
        ns_log warning "nsmcp: retention cleanup paused ($code); ingestion checkpoints preserved"
        return [dict create failed true code $code]
    } finally {
        try {
            if {$store ne {}} {
                accessRetentionPhase $token close-store
                $store close
            }
        } finally {
            set state [nsv_get $key state]
            set last [dict create startedAt [dict get $state startedAt] finishedAt [clock seconds] durationMs [expr {max(0,[clock clicks -milliseconds]-$began)}] outcome $outcome deleted $counts batches $batches]
            if {$code ne {}} {
                dict set last code $code
            }
            dict set state running false
            dict set state lastRun $last
            nsv_set $key state $state
            nsv_incr $gate busy -1
        }
    }
  • retentionStatus (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> retentionStatus

    Read current retention-maintenance status. Return retained maintenance observations without starting another pruning pass.

    Returns:
    The retention status dictionary.

    Testcases:
    No testcase defined.
    return [accessRetentionStatus]
  • retentionTick (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> retentionTick

    Run and reschedule one retention-maintenance callback. Use a one-shot scheduling chain so maintenance retries do not phase-lock with the ingestion timer.

    Returns:
    The scheduler callback result.

    Testcases:
    No testcase defined.
    # A single threaded one-shot chain avoids phase-locking a periodic
    # maintenance timer to the ingestion timer. Busy work retries later.
    set delay ${:retentionInterval}
    try {
        set result [:retain]
        if {[dict exists $result busy]} {
            set delay 1
        }
        return $result
    } finally {
        catch {
            ns_schedule_proc -once -thread $delay [self] retentionTick
        }
    }
  • summary (scripted, public)

     <instance of nsmcp::UnifiedAccessAnalytics[i]> summary options

    Query unified access summaries with bounded lock retry. Delegate to the superclass using the same normalized options after eligible transient store failures.

    Parameters:
    options (required)
    Tcl dictionary containing the operation options.
    Returns:
    The access summary dictionary.

    Testcases:
    No testcase defined.
    return [:accessRecordRetry ${:settings} [list next [list $options]]]