Reputation: 1621
We are placing PL/SQL function calls via Oracle JDBC driver (11.2) (using Spring JDBCTemplate* framework), and we have set com.ibm.ws.rsadapter.jdbc.*=all in WebSphere server's logging details (Runtime), but the captured data in the trace.log
file does not contain the actual translated PL/SQL function call nor the values of the parameters being passed to the function.
How can I achieve this logging detail? We are using SLF4j library for logging as well.
Upvotes: 0
Views: 728
Reputation: 1621
The following solution works regardless of what logging framework you have deployed for your application, i.e. Log4j, java.util.logging
, SLF4j, etc.:
Obtain a corresponding Oracle JDBC driver that has been compiled with tracing code enabled (ending with "_g.jar"). As long as the Oracle JDBC driver's major version matches the underlying database's, it's best to get the latest minor version (in our case, 11.2.0.4.0) as it outputs additional information for each call.
The latest diagnostic driver is going to be compatible with the older versions of your Oracle database. You can obtain them from Oracle's website here.
If you have used a WebSphere variable (i.e. Oracle JDBC Driver
) to specify the location of Oracle JDBC driver, place the diagnostic JDBC driver in the same folder as the regular driver (for ease of tracking). Nonetheless, you can place it anywhere on the file system.
Make sure the WebSphere user that starts up the server has proper file system permission to access the driver, i.e. ojdbc6_g.jar.
From WebSphere Admin Console, change the JDBC provider to point to the new driver:
To set the trace logging level:
Locate the server logging folder:
Restart the WebSphere server
Execute a code that invokes a PL/SQL function call
WebSphere should capture all the detail JDBC calls in trace.log
file now, i.e. calling schema_user.plsql_package.procedure()
with three parameters and values of parameter 1
, parameter 2
, and parameter 3
, would result in ({call ...}
is how I'm calling stored procedures from Spring's JdbcTemplate*
, but you can see how at the low level, Oracle driver translates it into a PL/SQL anonymous block call):
...
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Enter: 1, "parameter 1", 2
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Public Enter: 1, "parameter 1"
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 1, "parameter 1", 2
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 1, "parameter 1", 2, 0
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 1, "parameter 1", 2, 0
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 1, oracle.sql.NUMBER@42764276
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.0409ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.1926ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.2515ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.3107ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Exit [0.4817ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Exit [0.5556ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Enter: 2, "parameter 2"
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Public Enter: 2, "parameter 2"
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 2, "parameter 2"
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 2, "parameter 2"
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.0049ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.0691ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Exit [0.1276ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Exit [0.2008ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Enter: 3, "parameter 3"
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Public Enter: 3, "parameter 3"
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 3, "parameter 3"
[1/20/15 10:22:14:431 EDT] 00000020 driver 2 263D263D Enter: 3, "parameter 3"
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.0036ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver < 263D263D Exit [0.0549ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver 1 263D263D Exit [0.1094ms]
[1/20/15 10:22:14:431 EDT] 00000020 driver Z 263D263D Exit [0.161ms]
...
[1/20/15 10:22:14:433 EDT] 00000020 driver 2 32B732B7 Enter: "
{call schema_user.plsql_package.procedure(
param_1 => :param_1,
param_2 => :param_2,
param_3 => :param_3)}"
...
[1/20/15 10:22:14:434 EDT] 00000020 driver 2 32B732B7 Return:
BEGIN schema_user.plsql_package.procedure(
param_1 => :param_1,
param_2 => :param_2,
param_3 => :param_3); END;
...
The Oracle JDBC driver does perform caching of stored procedure calls made by the applications. Consequently, after the first invocation, the log file does not capture all the needed information that it does on the first try -- the scope of captured information is not going to be as comprehensive as the first invocation. Moreover, the trace logging is detailed enough that can make the parsing the interested sections unwieldy.
Therefore, in order to purge the cached stored procedure calls by the driver after the first invocation, follow the instructions below:
Log-in to WebSphere Admin Console (Integrated Solutions Console)
Navigate to Resources -> JDBC -> Data sources
Check an appropriate data source box which handles procedure calls, if any different
Click the "Manage state..." button on the top of the grid table
On "JCA lifecycle management" page, check box the same resource
Click the "Purge" button
Also, if you are running/testing your WebSphere in the Windows environment, you can use SnakeTail tool to tail
(like Unix/Linux systems) trace.log
file (quite fast and responsive with large buffer size).
Upvotes: 1