::nsmcp::Tool ::nsmcp::Tool describe execute init jsonArguments name permission validate ::nsmcp::Object ::nsmcp::Object dict getdef ::nsmcp::Tool->::nsmcp::Object ::nsmcp::LogTool ::nsmcp::LogTool arguments execute validate ::nsmcp::LogTool->::nsmcp::Tool

Class ::nsmcp::LogTool

::nsmcp::LogTool[i] create ... \
           [ -adminExample (default "") ] \
           [ -adminSummary (default "") ] \
           [ -description:required description:required ] \
           [ -inputSchema (default " { "type": "object", "properties": {}, "additionalProperties": false } ") ] \
           [ -name:required name:required ] \
           [ -operation:required operation:required ] \
           [ -outputSchema (default "") ] \
           [ -permission:required permission:required ] \
           [ -service:required service:required ]

Defined in /usr/local/ns/tcl/nsmcp/log-tools.tcl

Class Relations

  • class: ::nx::Class[i]
  • superclass: ::nsmcp::Tool[i]
::nx::Class create ::nsmcp::LogTool \
     -superclass ::nsmcp::Tool

Methods (to be applied on instances)

  • execute (scripted, public)

     <instance of nsmcp::LogTool[i]> execute context arguments

    Dispatch a validated log-diagnostic tool request. Select the configured operation and route it through the owned job service or cached result interface.

    Parameters:
    context (required)
    Authenticated request context carrying the principal, grants and selected server.
    arguments (required)
    Rooted ns_json typed triples for the tool's JSON argument object.
    Returns:
    A rooted JSON tool-result object, including availability or job metadata as appropriate.

    Testcases:
    No testcase defined.
    set values [:arguments $arguments]
    switch ${:operation} {
        errors {
            return [${:service} start $context errors [dict merge {severity Error literal {} limit 100} $values]]
        }
        requestContext {
            if {[dict exists $values identifier]} {
                return [${:service} start $context requestContext [dict get $values identifier]]
            }
            set ids {}
            foreach {i t id} [dict get $values identifiers] {
                lappend ids $id
            }
            return [${:service} start $context requestContexts [dict create identifiers $ids limit [:dict getdef $values limit 100]]]
        }
        results {
            if {[dict exists $values jobHandle]} {
                return [${:service} poll $context [dict get $values jobHandle]]
            }
            set values [dict merge {cursor 0 limit 20 includePeerAddresses false} $values]
            return [${:service} results $context [dict get $values resultHandle] [dict get $values cursor]  [dict get $values limit] [dict get $values includePeerAddresses]]
        }
    }
  • validate (scripted, public)

     <instance of nsmcp::LogTool[i]> validate arguments

    Validate the configured log operation's arguments. Decode the rooted JSON argument object and enforce this tool's option, range and combination constraints.

    Parameters:
    arguments (required)
    Rooted ns_json typed triples for the tool's JSON argument object.
    Returns:
    An empty result on success; invalid input raises RPC error -32602.

    Testcases:
    No testcase defined.
    if {[lindex $arguments 1] ne "object"} {
        return -code error -errorcode {NSMCP RPC -32602} "Expected arguments object"
    }
    set allowed [dict get [dict create errors {severity literal limit} requestContext {identifier identifiers limit} results {jobHandle resultHandle cursor limit includePeerAddresses}] ${:operation}]
    foreach {key type value} [lindex $arguments 2] {
        if {$key ni $allowed} {
            return -code error -errorcode {NSMCP RPC -32602} "Unknown log argument"
        }
        set expected string
        if {$key eq "limit"} {
            set expected number
        }
        if {$key eq "identifiers"} {
            set expected array
        }
        if {$key eq "includePeerAddresses"} {
            set expected boolean
        }
        if {$type ne $expected} {
            return -code error -errorcode {NSMCP RPC -32602} "Invalid log argument type"
        }
        if {$key eq "literal" && ($value eq "" || [string length [encoding convertto utf-8 $value]] > 1024
            || [regexp {[\x00\r\n]} $value])} {
            return -code error -errorcode {NSMCP RPC -32602} "Expected a nonempty single-line literal of at most 1024 UTF-8 bytes"
        }
        if {$key eq "identifiers"} {
            if {[llength $value] == 0 || [llength $value] > 60} {
                return -code error -errorcode {NSMCP RPC -32602} "Expected 1..20 identifiers"
            }
            foreach {i t id} $value {
                if {$t ne "string" || [string length [encoding convertto utf-8 $id]] > 512 || ![::nsmcp::logRecordParser validRequestIdentifier $id]} {
                    return -code error -errorcode {NSMCP RPC -32602} "Expected dash-delimited log-thread identifiers"
                }
            }
        }
        if {$key eq "severity" && $value ni {Warning Error Fatal Bug}} {
            return -code error -errorcode {NSMCP RPC -32602} "Expected Warning, Error, Fatal or Bug"
        }
        if {$key in {jobHandle resultHandle} && ![regexp {^[0-9a-f]{64}$} $value]} {
            return -code error -errorcode {NSMCP RPC -32602} "Invalid log handle"
        }
        if {$key eq "limit" && (![string is integer -strict $value] || $value < 1 || $value > 100)} {
            return -code error -errorcode {NSMCP RPC -32602} "Limit must be between 1 and 100"
        }
        if {$key eq "cursor" && (![string is entier -strict $value] || $value < 0)} {
            return -code error -errorcode {NSMCP RPC -32602} "Invalid cursor"
        }
    }
    set values [:arguments $arguments]
    if {${:operation} eq "requestContext"} {
        if {[dict exists $values identifier] == [dict exists $values identifiers]} {
            return -code error -errorcode {NSMCP RPC -32602} "Supply exactly one of identifier or identifiers"
        }
        if {[dict exists $values identifier] && (![::nsmcp::logRecordParser validRequestIdentifier [dict get $values identifier]] || [dict exists $values limit])} {
            return -code error -errorcode {NSMCP RPC -32602} "Expected a dash-delimited log-thread identifier; limit applies to batches"
        }
    }
    if {${:operation} eq "results"} {
        if {[dict exists $values jobHandle] == [dict exists $values resultHandle]} {
            return -code error -errorcode {NSMCP RPC -32602} "Supply exactly one of jobHandle (poll a job) or resultHandle (read a page)"
        }
        if {[dict exists $values jobHandle] && [dict size $values]!=1} {
            return -code error -errorcode {NSMCP RPC -32602} "Poll with jobHandle alone. Paging and includePeerAddresses apply to resultHandle pages; for access summaries set includePeerAddresses on access_summary"
        }
    }