blob: 1a94b6c348b49bccc9daed5ee6f91be2f004ddf2 [file] [log] [blame]
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.gjc.util;
import static java.util.logging.Level.FINEST;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.glassfish.api.jdbc.SQLTraceListener;
import org.glassfish.api.jdbc.SQLTraceRecord;
import com.sun.gjc.monitoring.JdbcRAConstants;
import com.sun.gjc.monitoring.SQLTraceProbeProvider;
import com.sun.logging.LogDomains;
/**
* Implementation of SQLTraceListener to listen to events related to a sql
* record tracing. The registry allows multiple listeners to listen to the sql
* tracing events. Maintains a list of listeners.
*
* @author Shalini M
*/
public class SQLTraceDelegator implements SQLTraceListener {
private static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER);
// List of listeners
protected List<SQLTraceListener> sqlTraceListenersList;
private String poolName;
private String appName;
private String moduleName;
private SQLTraceProbeProvider probeProvider = null;
public SQLTraceProbeProvider getProbeProvider() {
return probeProvider;
}
public SQLTraceDelegator(String poolName, String appName, String moduleName) {
this.poolName = poolName;
this.appName = appName;
this.moduleName = moduleName;
probeProvider = new SQLTraceProbeProvider();
}
/**
* Add a listener to the list of sql trace listeners maintained by this
* registry.
*
* @param listener
*/
public void registerSQLTraceListener(SQLTraceListener listener) {
if (sqlTraceListenersList == null) {
sqlTraceListenersList = new ArrayList<SQLTraceListener>();
}
sqlTraceListenersList.add(listener);
}
public void sqlTrace(SQLTraceRecord record) {
if (sqlTraceListenersList != null) {
for (SQLTraceListener listener : sqlTraceListenersList) {
try {
listener.sqlTrace(record);
} catch (Exception e) {
// it is possible that any of the implementations may fail processing a trace
// record.
// do not propagate such failures. Log them as FINEST.
if (_logger.isLoggable(FINEST)) {
_logger.log(FINEST,
"exception from one of the SQL trace listeners [" + listener.getClass().getName() + "]",
e);
}
}
}
}
if (record != null) {
record.setPoolName(poolName);
String methodName = record.getMethodName();
// Check if the method name is one in which sql query is used
if (isMethodValidForCaching(methodName)) {
Object[] params = record.getParams();
if (params != null && params.length > 0) {
String sqlQuery = null;
for (Object param : params) {
if (param instanceof String) {
sqlQuery = param.toString();
}
break;
}
if (sqlQuery != null) {
probeProvider.traceSQLEvent(poolName, appName, moduleName, sqlQuery);
}
}
}
}
}
/**
* Check if the method name from the sql trace record can be used to retrieve a
* sql string for caching purpose. Most of the method names do not contain a sql
* string and hence are unusable for caching the sql strings. These method names
* are filtered in this method.
*
* @param methodName
* @return true if method name can be used to get a sql string for caching.
*/
private boolean isMethodValidForCaching(String methodName) {
return JdbcRAConstants.validSqlTracingMethodNames.contains(methodName);
}
}