Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 81 additions & 17 deletions PAS/Management/OEManager/ABL/conf/oemanager.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,25 @@
<echo message="${line.separator} ${util.name} inventory - Bundle useful PAS instance files (as .zip) for support tickets"/>
<echo message="${line.separator}"/>
<echo message="${line.separator} Status/Info:"/>
<echo message="${line.separator} ${util.name} status - [RO] Obtain MSAgent/connection status information for an ABL App"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [OPTIONAL] -Dbasemem=${basemem} - Minimum memory threshold (bytes) to consider as 'unused' agent sessions"/>
<echo message="${line.separator} ${util.name} stacks - [RO] Obtain stack information for all MSAgents for an ABL App"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [OPTIONAL] -Dpid=[AGENT_PID] - Limit stack information to a specific MSAgent process ID"/>
<echo message=" [OPTIONAL] -Dsessid=[SESSION_ID] - Limit stack information to a specific ABL Session ID"/>
<echo message=" Requires specifying an MSAgent via -Dpid=[AGENT_PID]"/>
<echo message="${line.separator} ${util.name} flush - [RO] Flush the available deferred log buffer to agent log file"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message="${line.separator} ${util.name} locks - [RO] Display database users and their table locks related to an MSAgent-Session"/>
<echo message=" This utilizes a single DBConnection; edit the 'locks' task in build.xml to add more as necessary"/>
<echo message=" Note: Only provides session data if using self-service DB connections for OE versions under 12.5"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [REQUIRED] -Dpf=[PF_NAME] - PF file to use for database connection(s)"/>
<echo message="${line.separator} ${util.name} users - [RO] Alias for 'locks' task"/>
<echo message="${line.separator} ${util.name} status - [RO] Obtain MSAgent/connection status information for an ABL App"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [OPTIONAL] -Dbasemem=${basemem} - Minimum memory threshold (bytes) to consider as 'unused' agent sessions"/>
<echo message="${line.separator} ${util.name} stacks - [RO] Obtain stack information for all MSAgents for an ABL App"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [OPTIONAL] -Dpid=[AGENT_PID] - Limit stack information to a specific MSAgent process ID"/>
<echo message=" [OPTIONAL] -Dsessid=[SESSION_ID] - Limit stack information to a specific ABL Session ID"/>
<echo message=" Requires specifying an MSAgent via -Dpid=[AGENT_PID]"/>
<echo message="${line.separator} ${util.name} flush - [RO] Flush the available deferred log buffer to agent log file"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message="${line.separator} ${util.name} locks - [RO] Display database users and their table locks related to an MSAgent-Session"/>
<echo message=" This utilizes a single DBConnection; edit the 'locks' task in build.xml to add more as necessary"/>
<echo message=" Note: Only provides session data if using self-service DB connections for OE versions under 12.5"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [REQUIRED] -Dpf=[PF_NAME] - PF file to use for database connection(s)"/>
<echo message="${line.separator} ${util.name} requests - [RO] Display a summary of the last 1,000 requests related to an MSAgent"/>
<echo message=" [REQUIRED] -Dablapp=${ablapp} - ABL Application name, defaulting to the instance name if not changed"/>
<echo message=" [OPTIONAL] -Dpid=[AGENT_PID] - Obtain request information for a specific MSAgent process ID"/>
<echo message="${line.separator} ${util.name} users - [RO] Alias for 'locks' task"/>
<echo message="${line.separator}"/>
<echo message="${line.separator} Agent Management:"/>
<echo message="${line.separator} ${util.name} add - Add (read: start) one new MSAgent for an ABL App"/>
Expand Down Expand Up @@ -712,7 +715,8 @@

<!-- Runs all the targets in a particular order (least to most termination) -->
<antcall target="status"/>
<antcall target="stacks"/>
<antcall target="requests"/>
<antcall target="stacks"/>
<antcall target="flush"/>
<antcall target="trimhttp"/>
<antcall target="trimidle"/>
Expand Down Expand Up @@ -782,6 +786,66 @@
</if>
</target>

<target name="requests">
<init_oe/> <!-- Initialize all OpenEdge properties. -->

<fail message="PAS instance port (-Dport) was not provided.">
<condition>
<or>
<equals arg1="${port}" arg2=""/>
<not>
<isset property="port"/>
</not>
</or>
</condition>
</fail>

<if>
<isset property="isOE11"/>
<then>
<!-- OpenEdge 11.7 does not properly handle passing parameters via PCTDynRun. -->
<PCTRun
dlcHome="${dlcHome}"
graphicalMode="false"
tempDir="${output.dir}"
procedure="${proc.path}getRequests${proc.ext}">
<propath>
<pathelement path="${basedir}"/>
<pathelement path="${dlcHome}/tty/netlib/OpenEdge.Net.pl"/>
<pathelement path="${dlcHome}/tty/OpenEdge.ServerAdmin.pl"/>
</propath>
<Parameter name="Scheme" value="${scheme}"/>
<Parameter name="Host" value="${host}"/>
<Parameter name="Port" value="${port}"/>
<Parameter name="UserID" value="${userid}"/>
<Parameter name="PassWD" value="${passwd}"/>
<Parameter name="ABLApp" value="${ablapp}"/>
<Parameter name="ProcID" value="${pid}"/>
</PCTRun>
</then>
<else>
<PCTDynRun
dlcHome="${dlcHome}"
graphicalMode="false"
tempDir="${output.dir}"
procedure="${proc.path}getRequests${proc.ext}">
<propath>
<pathelement path="${basedir}"/>
<pathelement path="${dlcHome}/tty/netlib/OpenEdge.Net.pl"/>
<pathelement path="${dlcHome}/tty/OpenEdge.ServerAdmin.pl"/>
</propath>
<Parameter name="Scheme" value="${scheme}"/>
<Parameter name="Host" value="${host}"/>
<Parameter name="Port" value="${port}"/>
<Parameter name="UserID" value="${userid}"/>
<Parameter name="PassWD" value="${passwd}"/>
<Parameter name="ABLApp" value="${ablapp}"/>
<Parameter name="ProcID" value="${pid}"/>
</PCTDynRun>
</else>
</if>
</target>

<target name="stacks">
<init_oe/> <!-- Initialize all OpenEdge properties. -->

Expand Down
2 changes: 1 addition & 1 deletion PAS/Management/OEManager/ABL/release.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2024-05-01T13:06:38.644
2024-12-12T16:13:23.207
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020-2023 Progress Software Corporation
Copyright 2020-2024 Progress Software Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -96,7 +96,7 @@ repeat:
assign cConnDetail = hConnDetFld:buffer-value().
if num-entries(cConnDetail, ":") ge 4 then
assign
iConnectPID = integer(entry(3, cConnDetail, ":"))
iConnectPID = int64(entry(3, cConnDetail, ":"))
iSessionID = if entry(4, cConnDetail, ":") begins "AS-" and num-entries(entry(4, cConnDetail, ":"), "-") gt 1
then integer(entry(2, entry(4, cConnDetail, ":"), "-")) else ?
.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Copyright 2020-2024 Progress Software Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Author(s): Dustin Grau ([email protected])
*
* Gets MSAgent requests for an ABLApp.
* Usage: getRequests.p <params>
* Parameter Default/Allowed
* Scheme [http|https]
* Hostname [localhost]
* PAS Port [8810]
* UserId [tomcat]
* Password [tomcat]
* ABL App [oepas1]
* AgentID [#]
*/

using OpenEdge.ApplicationServer.Util.OEManagerConnection.
using OpenEdge.ApplicationServer.Util.OEManagerEndpoint.
using OpenEdge.Core.Json.JsonPropertyHelper.
using OpenEdge.Core.JsonDataTypeEnum.
using Progress.Json.ObjectModel.JsonObject.
using Progress.Json.ObjectModel.JsonArray.
using Progress.Json.ObjectModel.JsonDataType.

define variable cOutFile as character no-undo.
define variable oAgents as JsonArray no-undo.
define variable oAgent as JsonObject no-undo.
define variable oRequests as JsonArray no-undo.
define variable iLoop as integer no-undo.
define variable iPID as integer no-undo.
define variable cPID as character no-undo.

/* Manage the server connection to the OEManager webapp */
define variable oMgrConn as OEManagerConnection no-undo.
define variable cScheme as character no-undo initial "http".
define variable cHost as character no-undo initial "localhost".
define variable cPort as character no-undo.
define variable cUserId as character no-undo.
define variable cPassword as character no-undo.
define variable cAblApp as character no-undo.

/* Check for passed-in arguments/parameters. */
if num-entries(session:parameter) ge 6 then
assign
cScheme = entry(1, session:parameter)
cHost = entry(2, session:parameter)
cPort = entry(3, session:parameter)
cUserId = entry(4, session:parameter)
cPassword = entry(5, session:parameter)
cAblApp = entry(6, session:parameter)
cPID = entry(7, session:parameter)
.
else
assign
cScheme = dynamic-function("getParameter" in source-procedure, "Scheme") when (dynamic-function("getParameter" in source-procedure, "Scheme") gt "") eq true
cHost = dynamic-function("getParameter" in source-procedure, "Host") when (dynamic-function("getParameter" in source-procedure, "Host") gt "") eq true
cPort = dynamic-function("getParameter" in source-procedure, "Port") when (dynamic-function("getParameter" in source-procedure, "Port") gt "") eq true
cUserId = dynamic-function("getParameter" in source-procedure, "UserID") when (dynamic-function("getParameter" in source-procedure, "UserID") gt "") eq true
cPassword = dynamic-function("getParameter" in source-procedure, "PassWD") when (dynamic-function("getParameter" in source-procedure, "PassWD") gt "") eq true
cAblApp = dynamic-function("getParameter" in source-procedure, "ABLApp") when (dynamic-function("getParameter" in source-procedure, "ABLApp") gt "") eq true
cPID = dynamic-function("getParameter" in source-procedure, "ProcID") when (dynamic-function("getParameter" in source-procedure, "ProcID") gt "") eq true
.

/* Create and OEManager connection for API calls. */
assign oMgrConn = OEManagerConnection:Build(cScheme, cHost, integer(cPort), cUserId, cPassword).

if (cPID gt "") eq true then do:
assign oRequests = oMgrConn:GetAgentRequests(cAblApp, integer(cPID)).
if oRequests:Length gt 0 then do:
/* Write requests information from the specified MSAgent. */
message substitute("Saving requests information for MSAgent PID &1...", cPID).
assign cOutFile = substitute("agentRequests_&1_&2.json", cPID, replace(iso-date(now), ":", "_")).
oRequests:WriteFile(session:temp-directory + cOutFile, true). /* Write entire response to disk. */
message substitute("~tRequests data written to &1", cOutFile).
end.
else
message substitute("No requests data for MSAgent PID &1", cPID).
end. // cPID Present
else do:
/* Otherwise output requests for all agents of an ABL Application. */

/* Initial URL to obtain a list of all MSAgents for an ABL Application. */
message substitute("Looking for MSAgents of &1...", cAblApp).
assign oAgents = oMgrConn:GetAgents(cAblApp).
if oAgents:Length eq 0 then
message "No MSAgents running".
else
AGENTBLK:
do iLoop = 1 to oAgents:Length
on error undo, next AGENTBLK
on stop undo, next AGENTBLK:
oAgent = oAgents:GetJsonObject(iLoop).

/* We need the agent PID for user-friendly displays since that's how we identify the process. */
if JsonPropertyHelper:HasTypedProperty(oAgent, "pid", JsonDataType:string) then
assign iPID = integer(oAgent:GetCharacter("pid")).

/* Write requests information from any available MSAgents. */
if iPID gt 0 and oAgent:GetCharacter("state") eq "available" then do:
assign oRequests = oMgrConn:GetAgentRequests(cAblApp, iPID).
if oRequests:Length gt 0 then do:
message substitute("Saving requests information for MSAgent PID &1...", iPID).
assign cOutFile = substitute("agentRequests_&1_&2.json", iPID, replace(iso-date(now), ":", "_")).
oRequests:WriteFile(session:temp-directory + cOutFile, true). /* Write entire response to disk. */
message substitute("~tRequests data written to &1", cOutFile).
end.
else
message substitute("No requests data for MSAgent PID &1", iPID).
end. /* agent state = available */
else
message substitute("Agent PID &1 not AVAILABLE, skipping requests.", iPID).
end. /* iLoop - agent */
end. // All Agents

catch err as Progress.Lang.Error:
put unformatted substitute("~nError while communicating with PASOE instance: &1", err:GetMessage(1)) skip.
end catch.
finally:
/* Return value expected by PCT Ant task. */
{&_proparse_ prolint-nowarn(returnfinally)}
return string(0).
end finally.
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ end finally.
/* PROCEDURES / FUNCTIONS */

function FormatDecimal returns character ( input pcValue as character ):
return trim(string(int64(pcValue) / 60000, ">>9.9")).
return trim(string(int64(pcValue) / 60000, "->>9.9")).
end function. /* FormatDecimal */

function FormatMemory returns character ( input piValue as int64, input plTrim as logical ):
Expand Down Expand Up @@ -212,9 +212,9 @@ end function. /* FormatMsTime */

function FormatLongNumber returns character ( input pcValue as character, input plTrim as logical ):
if plTrim then
return trim(string(int64(pcValue), ">>>,>>>,>>9")).
return trim(string(int64(pcValue), "->>>,>>>,>>9")).
else
return string(int64(pcValue), ">>>,>>>,>>9").
return string(int64(pcValue), "->>>,>>>,>>9").
end function. /* FormatCharAsNumber */

function FormatCharAsNumber returns character ( input pcValue as character ):
Expand Down Expand Up @@ -663,7 +663,7 @@ procedure GetSessions:
JsonPropertyHelper:HasTypedProperty(oMetrics, "readErrors", JsonDataType:Number) then
put unformatted substitute("~t # Agent Responses Read: &1 (&2 Errors)",
FormatLongNumber(string(oMetrics:GetInteger("reads")), false),
trim(string(oMetrics:GetInteger("readErrors"), ">>>,>>>,>>9"))) skip.
trim(string(oMetrics:GetInteger("readErrors"), "->>>,>>>,>>9"))) skip.

/* Minimum, maximum, average times to read a response from the MSAgent. */
if JsonPropertyHelper:HasTypedProperty(oMetrics, "minAgentReadTime", JsonDataType:Number) and
Expand All @@ -680,15 +680,15 @@ procedure GetSessions:
JsonPropertyHelper:HasTypedProperty(oMetrics, "writeErrors", JsonDataType:Number) then
put unformatted substitute("~t # Agent Requests Written: &1 (&2 Errors)",
FormatLongNumber(string(oMetrics:GetInteger("writes")), false),
trim(string(oMetrics:GetInteger("writeErrors"), ">>>,>>>,>>9"))) skip.
trim(string(oMetrics:GetInteger("writeErrors"), "->>>,>>>,>>9"))) skip.

/* Number of clients connected at a particular time. */
/* Maximum number of concurrent clients. */
if JsonPropertyHelper:HasTypedProperty(oMetrics, "concurrentConnectedClients", JsonDataType:Number) and
JsonPropertyHelper:HasTypedProperty(oMetrics, "maxConcurrentClients", JsonDataType:Number) then
put unformatted substitute("~tConcurrent Connected Clients: &1 (Max: &2)",
FormatLongNumber(string(oMetrics:GetInteger("concurrentConnectedClients")), false),
trim(string(oMetrics:GetInteger("maxConcurrentClients"), ">>>,>>>,>>9"))) skip.
trim(string(oMetrics:GetInteger("maxConcurrentClients"), "->>>,>>>,>>9"))) skip.

/* Total time that reserved ABL sessions had to wait before executing. */
if JsonPropertyHelper:HasTypedProperty(oMetrics, "totReserveABLSessionWaitTime", JsonDataType:Number) then
Expand Down
Loading