Consultor Eletrônico



Kbase P173889: How to start the PROFILER from a WebSpeed application
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   23/09/2010
Status: Unverified

GOAL:

How to start the PROFILER from a WebSpeed application

GOAL:

What is the best place to start profiling in a WebSpeed application?

FACT(s) (Environment):

All Supported Operating Systems
Progress 9.x
OpenEdge 10.x

FIX:

What is the Profiler:

The PROFILER is a system handle whose attributes and methods can be used to record execution performance information of ABL code.

When performance problems occur in a WebSpeed environment the PROFILER may help to track down the bottleneck, or at least rule out that the problem exists in the ABL application. A WebSpeed request begins in a web browser, which communicates with a messenger executable on the Webserver. The messenger communicates the information from the request to the WebSpeed broker, which hands the request off to a WebSpeed agent.

The WebSpeed agent is simply an _progres executable which is capable of streaming its output back through the Webserver to the web browser which initiated the request. Since there are multiple pieces of this configuration, bottlenecks can exist at any level, but ruling out performance bottlenecks in the ABL code that is executing is a good place to start when trying to diagnose a performance issue.

Where to Start/Stop the PROFILER:

The best place to start profiling in a WebSpeed application is in the the web dispatcher program (tty/web/objects/web-disp.p). This program is run when a request is initiated on a WebSpeed agent and handles dispatching the call to the program that was indicated in the WebSpeed request. There is code in this program that parses the program name from the request and runs it, and this is generally the best place to start PROFILING if you have no idea where in the ABL code the performance bottleneck exists.

To begin with, check to see if your application already has a customized web-disp.p. Most WebSpeed application providers add customizations to this program for one reason or another and have a local copy that is part of their application. The best strategy for customizing this is to make a local copy of this and place it in an application directory that is higher in the PROPATH than $DLC/tty/web/objects.

Once you have a local copy, open it and search for the following statement:
'RUN run-web-object IN web-utilities-hdl (AppProgram) NO-ERROR.'

The above line of code is the line that runs your application program and the AppProgram variable is the name of the program it's looking to run. This is the best place to start the PROFILER if you do not know where specifically in your WebSpeed application program the bottleneck exists.

The PROFILER slows down application performance significantly, so you don't generally want to start it for every request. It is a good idea to either tie the starting of the PROFILER to a specific program, a specific user or a setting in your application that the user or an administrator may have access to. You could either check the name of AppProgram, or use get-value to check the value of a URL encoded variable or cookie sent from the application to trigger the start of PROFILING.

How to Start the PROFILER:

This is gone into in greater depth in solution article # 19495, however starting the PROFILER is as simple as setting the ENABLED and PROFILING attributes of the PROFILER system handle to TRUE, then performing the opposite action, followed by firing the WRITE-DATA() method on same. This will provide you with a file named profile.out in your WebSpeed agent's working directory or the directory specified by the -T parameter on agent startup.

Below is an example of one way to configure the PROFILER to get the most out of the output:


DEFINE VARIABLE lStartProfiler AS LOGICAL NO-UNDO.
DEFINE VARIABLE cUserId AS CHARACTER NO-UNDO.
DEFINE VARIABLE cProfFile AS CHARACTER NO-UNDO.
DEFINE VARIABLE iCounter AS INTEGER NO-UNDO.
DEFINE VARIABLE cDirectory AS CHARACTER NO-UNDO.
DEFINE VARIABLE cSlash AS CHARACTER NO-U.NDO.
DEFINE VARIABLE cFilename AS CHARACTER NO-UNDO.
lStartProfiler = ((get-value('startProfiling') GT "") EQ TRUE). /* This ensures that a value has been set via a cookie or url-encoded variable named startProfiling */

IF lStartProfiler THEN DO:
cSlash = (IF OPSYS EQ "UNIX" THEN "/" ELSE "~\").

/* Create a directory for profiling output under the current directory if one does not already exist */
FILE-INFO:FILE-NAME = "profiler_output".
IF FILE-INFO:FULL-PATHNAME EQ ? OR
NOT (FILE-INFO:FILE-TYPE BEGINS "D") THEN
OS-CREATE-DIR "profiler_output".

IF OS-ERROR GT 0 OR
FILE-INFO:FULL-PATHNAME EQ ? THEN
cDirectory = RIGHT-TRIM(SESSION:TEMP-DIRECTORY,cSlash).
ELSE cDirectory = FILE-INFO:FULL-PATHNAME.

/* Loop through all connected databases to see if you can identify the connected userid.
Alternative methods would be to include this in the web request as a cookie or variable */
DO iCounter = 1 TO NUM-DBS:
cUserId = USERID(LDBNAME(iCounter)).
IF (cUserId GT "") EQ TRUE THEN LEAVE.
END.

/* Initialize the output filename to begin with 'profiler', include the program name being
executed, the userid of the user that initiated the request, a date-time stamp and increment
it if the filename already exists.*/
cFileName = "profiler_" + (IF (AppProgram GT "") EQ TRUE THEN AppProgram + "_" ELSE "") +
(IF (cUserId GT "") EQ TRUE THEN cUserId + "_" ELSE "") +
REPLACE(STRING(TODAY,"99/99/9999"),"/","") + "_" +
REPLACE(TRIM(REPLACE(STRING(TIME,"HH:MM:SS AM"),":",""))," ","_").
ASSIGN iCounter = 0
FILE-INFO:FILE-NAME = cDirectory + cSlash + cFileName + ".log".
DO WHILE FILE-INFO:FULL-PATHNAME NE ?:
iCounter = iCounter + 1.
FILE-INFO:FILE-NAME = cDirectory + cSlash + cFileName + "_" + STRING(iCounter) + ".log".
END.

ASSIGN PROFILER:FILENAME = cDirectory + cSlash + cFileName +
(IF iCounter GT 0 THEN "_" + STRING(iCounter) ELSE "") + ".log"
PROFILER:DESCRIPTION = "Profiler data capture " + cFileName
PROFILER:LISTINGS = TRUE /* Best option if you wish to see the offending code */
PROFILER:DIRECTORY = cDirectory /* Listing files will be generated here */
PROFILER:ENABLED = TRUE
PROFILER:PROFILING = TRUE.
END. /* IF lStartProfiler */

RUN run-web-object IN web-utilities-hdl (AppProgram) NO-ERROR.

IF lStartProfiler THEN DO:
ASSIGN PROFILER:PROFILING = FALSE
PROFILER:ENABLED = FALSE.
PROFILER:WRITE-DATA().
END..