/*
* Copyright 2014 NAVER Corp.
*
* 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.
*/
package com.navercorp.pinpoint.plugin.jdbc.postgresql.interceptor;
import com.navercorp.pinpoint.bootstrap.context.*;
import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin;
import com.navercorp.pinpoint.bootstrap.interceptor.annotation.TargetMethod;
import com.navercorp.pinpoint.bootstrap.interceptor.annotation.TargetMethods;
import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DatabaseInfoAccessor;
import com.navercorp.pinpoint.bootstrap.plugin.jdbc.ParsingResultAccessor;
import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo;
import com.navercorp.pinpoint.bootstrap.util.InterceptorUtils;
/**
* @author Brad Hong
*/
@TargetMethods({
@TargetMethod(name="prepareStatement", paramTypes={ "java.lang.String", "int", "int", "int" })
})
public class PostgreSqlPreparedStatementCreateInterceptor3 extends SpanEventSimpleAroundInterceptorForPlugin {
public PostgreSqlPreparedStatementCreateInterceptor3(TraceContext context, MethodDescriptor descriptor) {
super(context, descriptor);
}
@Override
public void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) {
DatabaseInfo databaseInfo = null;
if (target instanceof DatabaseInfoAccessor) {
databaseInfo = ((DatabaseInfoAccessor)target)._$PINPOINT$_getDatabaseInfo();
}
if (databaseInfo == null) {
databaseInfo = UnKnownDatabaseInfo.INSTANCE;
}
recorder.recordServiceType(databaseInfo.getType());
recorder.recordEndPoint(databaseInfo.getMultipleHost());
recorder.recordDestinationId(databaseInfo.getDatabaseId());
}
@Override
protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) {
final boolean success = InterceptorUtils.isSuccess(throwable);
if (success) {
if (target instanceof DatabaseInfoAccessor) {
// set databaseInfo to PreparedStatement only when preparedStatement is generated successfully.
DatabaseInfo databaseInfo = ((DatabaseInfoAccessor)target)._$PINPOINT$_getDatabaseInfo();
if (databaseInfo != null) {
if (result instanceof DatabaseInfoAccessor) {
((DatabaseInfoAccessor)result)._$PINPOINT$_setDatabaseInfo(databaseInfo);
}
}
}
if (result instanceof ParsingResultAccessor) {
// 1. Don't check traceContext. preparedStatement can be created in other thread.
// 2. While sampling is active, the thread which creates preparedStatement could not be a sampling target. So record sql anyway.
String sql = (String) args[0];
ParsingResult parsingResult = traceContext.parseSql(sql);
if (parsingResult != null) {
((ParsingResultAccessor)result)._$PINPOINT$_setParsingResult(parsingResult);
} else {
if (logger.isErrorEnabled()) {
logger.error("sqlParsing fail. parsingResult is null sql:{}", sql);
}
}
}
}
}
@Override
public void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
if (result instanceof ParsingResultAccessor) {
ParsingResult parsingResult = ((ParsingResultAccessor)result)._$PINPOINT$_getParsingResult();
recorder.recordSqlParsingResult(parsingResult);
}
recorder.recordException(throwable);
recorder.recordApi(methodDescriptor);
}
}