From: David O. <da...@qc...> - 2018-02-13 12:27:10
|
Hi, We've been looking at profiling the execution times of various application-level procs running NaviServer. We want the ability to turn on profiling for selected commands, so we started off using Tcl traces in a manner similar to: http://nikit.tcl.tk/page/Profiling+with+execution+traces So we'd have a proc to set up a Tcl trace on command execution enter/leave in a list like so: proc instrument {args} { #| Takes list of commands and adds Tcl execution trace for entering and exit set script "" foreach cmd $args { append script "trace add execution $cmd enter profile_begin\n" append script "trace add execution $cmd leave profile_end\n" } } eval $script } At the start of each proc in the list we'd push the start time to a stack: proc profile_begin args { # Append current time to timer stack for this thread variable ::timerStack lappend ::timerStack [::tcl::clock::microseconds] } And then pop off the time when proc exits: proc profile_end {command_string code result op} { #| Pop value off timer stack for this thread and record a subsegment variable ::timerStack set start_time [lindex $::timerStack end] set end_time [::tcl::clock::microseconds] set ::timerStack [lrange $::timerStack 0 end-1] record_the_timing $command_string $start_time $end_time } It wasn't obvious to me how to set up these Tcl traces so they are active in each NaviServer interpreter, but after some trial and error, I could get a result by using ns_ictl to set up a callback on interpreter allocation and use that to set up the Tcl trace: ns_ictl trace allocate "instrument $cmd_list" This seems to work ok but has the disadvantage that I think I need to restart NaviServer in order to add or remove commands. So I wanted to ask: 1. Is there a more dynamic way of setting up Tcl traces across NaviServer interpreters? 2. Is anyone aware of a different/better way of profiling applications running under NaviServer? Regards, -- David |