public Connection monitorGetConnection(Connection connection, Object dataSource, long duration) throws SQLException { if (active && dataSource instanceof DataSource && !(connection instanceof P6Proxy)) { return ConnectionWrapper.wrap(connection, jdbcEventListener, ConnectionInformation.fromDataSource((DataSource) dataSource, connection, duration)); } else { return connection; } }
/** * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but * all callbacks happen on the same thread. * * <p>Uses {@link ThreadLocalSpan#CURRENT_TRACER} and this interceptor initializes before tracing. */ @Override public void onBeforeAnyExecute(StatementInformation info) { String sql = includeParameterValues ? info.getSqlWithValues() : info.getSql(); // don't start a span unless there is SQL as we cannot choose a relevant name without it if (sql == null || sql.isEmpty()) return; // Gets the next span (and places it in scope) so code between here and postProcess can read it Span span = ThreadLocalSpan.CURRENT_TRACER.next(); if (span == null || span.isNoop()) return; span.kind(Span.Kind.CLIENT).name(sql.substring(0, sql.indexOf(' '))); span.tag("sql.query", sql); parseServerIpAndPort(info.getConnectionInformation().getConnection(), span); span.start(); }
@Override public void onAfterAnyExecute(StatementInformation statementInformation, long timeElapsedNanos, SQLException e) { final Scope activeScope = tracingPlugin.getTracer().scopeManager().active(); if (activeScope != null) { final Span span = activeScope.span(); if (statementInformation.getConnectionInformation().getDataSource() instanceof DataSource && jdbcPlugin.isCollectSql()) { MetaData metaData = dataSourceUrlMap.get(statementInformation.getConnectionInformation().getDataSource()); Tags.PEER_SERVICE.set(span, metaData.serviceName); span.setTag("db.type", metaData.productName); span.setTag("db.user", metaData.userName); if (StringUtils.isNotEmpty(statementInformation.getSql())) { String sql = getSql(statementInformation.getSql(), statementInformation.getSqlWithValues()); Profiler.addIOCall(sql, timeElapsedNanos); span.setTag(AbstractExternalRequest.EXTERNAL_REQUEST_METHOD, getMethod(sql)); span.setTag(DB_STATEMENT, sql); } } tracingPlugin.getRequestMonitor().monitorStop(); } }
public static void logElapsed(int connectionId, long timeElapsedNanos, Category category, Loggable loggable) { // usually an expensive operation => cache where possible String sql = loggable.getSql(); String url = loggable.getConnectionInformation().getUrl(); if (logger != null && meetsThresholdRequirement(timeElapsedNanos) && isCategoryOk(category) && isLoggable(sql)) { doLogElapsed(connectionId, timeElapsedNanos, category, sql, loggable.getSqlWithValues(), url == null ? "" : url); } else if (isDebugEnabled()) { sql = loggable.getSqlWithValues(); debug("P6Spy intentionally did not log category: " + category + ", statement: " + sql + " Reason: logger=" + logger + ", isLoggable=" + isLoggable(sql) + ", isCategoryOk=" + isCategoryOk(category) + ", meetsTreshold=" + meetsThresholdRequirement(timeElapsedNanos)); } }
@Override public void onConnectionWrapped(ConnectionInformation connectionInformation) { final Metric2Registry metricRegistry = corePlugin.getMetricRegistry(); // at the moment stagemonitor only supports monitoring connections initiated via a DataSource if (connectionInformation.getDataSource() instanceof DataSource && corePlugin.isInitialized()) { DataSource dataSource = (DataSource) connectionInformation.getDataSource(); ensureUrlExistsForDataSource(dataSource, connectionInformation.getConnection()); MetaData metaData = dataSourceUrlMap.get(dataSource); metricRegistry.timer(getConnectionTemplate.build(metaData.serviceName)).update(connectionInformation.getTimeToGetConnectionNs(), TimeUnit.NANOSECONDS); final Span span = TracingPlugin.getCurrentSpan(); final Long connectionWrappedCountSum = incrementAndGetContextValue(span, CONNECTION_WRAPPED_COUNT_ATTRIBUTE, 1L); span.setTag("jdbc_get_connection_count", connectionWrappedCountSum); final double timeToGetConnectionMs = connectionInformation.getTimeToGetConnectionNs() / MILLISECOND_IN_NANOS; final Double connectionWaitTimeMsSum = incrementAndGetContextValue(span, TIME_TO_GET_CONNECTION_MS_ATTRIBUTE, timeToGetConnectionMs); span.setTag("jdbc_connection_wait_time_ms", connectionWaitTimeMsSum); } }
public static void log(Category category, Loggable loggable) { if (logger != null && isCategoryOk(category) && isLoggable(loggable.getSql())) { doLog(-1, category, loggable.getSql(), loggable.getSqlWithValues()); } }
@Override public void onAfterResultSetNext(ResultSetInformation resultSetInformation, long timeElapsedNanos, boolean hasNext, SQLException e) { resultSetInformation.getStatementInformation().incrementTimeElapsed(timeElapsedNanos); if (hasNext) { resultSetInformation.incrementCurrRow(); } }
@Override public void onAfterResultSetClose(ResultSetInformation resultSetInformation, SQLException e) { if (resultSetInformation.getCurrRow() > -1) { // If the result set has not been advanced to the first row, there is nothing to log. resultSetInformation.generateLogMessage(); } }
protected void logElapsed(Loggable loggable, long timeElapsedNanos, Category category, SQLException e) { P6LogQuery.logElapsed(loggable.getConnectionInformation().getConnectionId(), timeElapsedNanos, category, loggable); } }
/** {@inheritDoc} */ @Override public ConnectionInformation getConnectionInformation() { return this.statementInformation.getConnectionInformation(); } }
public static void info(String sql) { if (logger != null && isCategoryOk(Category.INFO)) { doLog(-1, Category.INFO, "", sql); } }
@Override public boolean matches(ConnectionInformation connectionInformation) { return connectionInformation.getConnection() != null; } });
/** * Creates a new {@link ConnectionInformation} instance for a {@link Connection} which will be obtained via a * {@link PooledConnection} * * @param pooledConnection the {@link PooledConnection} which created the {@link #connection} * @return a new {@link ConnectionInformation} instance */ public static ConnectionInformation fromPooledConnection(PooledConnection pooledConnection) { final ConnectionInformation connectionInformation = new ConnectionInformation(); connectionInformation.pooledConnection = pooledConnection; return connectionInformation; }
@Override public boolean addAll(Collection<? extends T> c) { boolean modified = false; for (T o : c) { if (add(o)) { modified = true; } } return modified; }
@Override public void onBeforeResultSetNext(ResultSetInformation resultSetInformation) { if (resultSetInformation.getCurrRow() > -1) { // Log the columns that were accessed except on the first call to ResultSet.next(). The first time it is // called it is advancing to the first row. resultSetInformation.generateLogMessage(); } }
public static void log(Category category, String prepared, String sql) { if (logger != null && isCategoryOk(category)) { doLog(-1, category, prepared, sql); } }
/** * Creates a new {@link ConnectionInformation} instance for a {@link Connection} which will be obtained via a * {@link CommonDataSource} * * @param dataSource the {@link javax.sql.CommonDataSource} which created the {@link #connection} * @return a new {@link ConnectionInformation} instance */ public static ConnectionInformation fromDataSource(CommonDataSource dataSource) { final ConnectionInformation connectionInformation = new ConnectionInformation(); connectionInformation.dataSource = dataSource; return connectionInformation; }
/** * This method should only be used in test scenarios * * @param connection the underlying connection (possibly a mock) * @return a new {@link ConnectionInformation} instance */ public static ConnectionInformation fromTestConnection(Connection connection) { final ConnectionInformation connectionInformation = new ConnectionInformation(); connectionInformation.connection = connection; return connectionInformation; }