- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
Class ::nsmcp::LogRedactor
::nsmcp::LogRedactorcreate ... \
[ -headerNames (default "authorization proxy-authorization cookie set-cookie x-api-key") ] \
[ -maskPeerAddresses:boolean (default "true") ] \
[ -maskUserIdentifiers:boolean (default "true") ] \
[ -queryParameters (default "__csrf_token csrf_token token access_token refresh_token id_token password passwd secret api_key apikey") ] \
[ -replacement (default "[REDACTED]") ]
Defined in /usr/local/ns/tcl/nsmcp/log-redaction.tcl
Class Relations
::nx::Class create ::nsmcp::LogRedactor \ -superclass ::nsmcp::ObjectMethods (to be applied on instances)
message (scripted, public)
<instance of nsmcp::LogRedactor> message text
Redact sensitive values in a log message. Apply configured header and token policies line by line before returning diagnostic evidence.
- Parameters:
- text (required)
- Text to inspect or redact.
- Returns:
- The redacted message text.
- Testcases:
- No testcase defined.
set lines {} foreach line [split $text \n] { if {[regexp {^([ \t]*(?::[ \t]*)?)([^:\s]+)[ \t]*:[ \t]*(.*)$} $line -> prefix name value] && [:sensitive $name ${:headerNames}]} { set line "${prefix}${name}: ${:replacement}" } else { set line [:queryValues $line] } if {${:maskPeerAddresses}} { if {[regexp -indices {^(\S+)[ \t]+\S+[ \t]+\S+[ \t]+\[[0-9]{2}/[A-Za-z]{3}/[0-9]{4}:} $line match peer]} { lassign $peer a b set line [string replace $line $a $b ${:replacement}] } set line [:identifiers $line {(peer(?:address|addr)?[ \t]*[:=]?[ \t]+)([0-9A-Fa-f:.]+)(?:[ \t,;]|$)}] } if {${:maskUserIdentifiers}} { set line [:identifiers $line {(user_id[ \t]*[:=]?[ \t]+)([0-9]+)(?:[ \t,;]|$)}] # The third field in the recognized access header is the user. if {[regexp -indices {^\S+[ \t]+\S+[ \t]+(\S+)[ \t]+\[[0-9]{2}/[A-Za-z]{3}/[0-9]{4}:} $line match user]} { lassign $user a b if {[string range $line $a $b] ne "-"} { set line [string replace $line $a $b ${:replacement}] } } } lappend lines $line } return [join $lines \n]page (scripted, public)
<instance of nsmcp::LogRedactor> page page
Redact every record in a result page. Retain pagination and coverage metadata while replacing its records with redacted copies.
- Parameters:
- page (required)
- Result-page dictionary containing records and coverage metadata.
- Returns:
- The redacted page dictionary.
- Testcases:
- No testcase defined.
set records {} foreach entry [dict get $page records] { lappend records [:record $entry] } dict set page records $records return $pagequeryValues (scripted, public)
<instance of nsmcp::LogRedactor> queryValues text
Redact sensitive query-parameter values in text. Decode names for policy matching while retaining the original URL spelling and avoiding value decoding.
- Parameters:
- text (required)
- Text to inspect or redact.
- Returns:
- Text with matching query values redacted.
- Testcases:
- No testcase defined.
set start 0 # Match literal query separators. Decode names, never values, for policy # comparison; retain the original URL spelling and nonsensitive values. while {[regexp -indices -start $start {[?&]([^=&#\s"<>]+)=([^&#\s"<>]*)} $text match key value]} { lassign $key a b set name [string range $text $a $b] if {[catch { ns_urldecode -charset utf-8 -- $name } decoded]} { set decoded $name } lassign $value a b if {[:sensitive $decoded ${:queryParameters}]} { set text "[string range $text 0 [expr {$a-1}]]${:replacement}[string range $text [expr {$b+1}] end]" set start [expr {$a+[string length ${:replacement}]}] } else { set start [expr {[lindex $match 1]+1}] } } return $textrecord (scripted, public)
<instance of nsmcp::LogRedactor> record entry
Redact one structured log record. Redact supported message and metadata fields and retain the record's redaction indicators.
- Parameters:
- entry (required)
- Structured log-record dictionary.
- Returns:
- The redacted record dictionary.
- Testcases:
- No testcase defined.
set original $entry if {[dict exists $entry message]} { dict set entry message [:message [dict get $entry message]] } if {[dict exists $entry mutexName]} { dict set entry mutexName [:message [dict get $entry mutexName]] } if {[dict exists $entry url]} { dict set entry url [:queryValues [dict get $entry url]] } if {${:maskPeerAddresses} && [dict exists $entry peerAddress] && [dict get $entry peerAddress] ne ""} { set peer [dict get $entry peerAddress] if {[dict exists $entry message]} { dict set entry message [string map [list $peer ${:replacement}] [dict get $entry message]] } dict set entry peerAddress ${:replacement} } dict set entry redacted [expr {$entry ne $original}] return $entry
- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
![[i]](/resources/acs-subsite/ZoomIn16.gif)