From 52dfcd52052c04a05c6f02824b2f5e0001bacd36 Mon Sep 17 00:00:00 2001 From: "koo.taejin" Date: Thu, 23 Feb 2017 13:56:55 +0900 Subject: [PATCH] [#2496] Add datasource metric collection 1. Change JdbcUrlParser management method 2. Change the collection properties of the DataSource (poolName -> databaseName) --- .../bootstrap/context/DatabaseInfo.java | 4 + .../bootstrap/context/TraceContext.java | 3 + .../plugin/ProfilerPluginSetupContext.java | 3 + .../plugin/jdbc/DefaultDatabaseInfo.java | 45 ++++-- .../jdbc/JdbcConnectionStringParser.java | 31 ++++ .../JdbcConnectionStringParserContext.java | 29 ++++ .../bootstrap/plugin/jdbc/JdbcUrlParser.java | 11 +- .../plugin/jdbc/UnKnownDatabaseInfo.java | 11 +- .../interceptor/DriverConnectInterceptor.java | 4 + .../DriverConnectInterceptor2.java | 111 +++++++++++++++ .../plugin/monitor/DataSourceMonitor.java | 2 - .../interceptor/MockTraceContext.java | 7 + .../thrift/stat/DataSourceBoMapper.java | 2 +- .../bo/codec/stat/v2/DataSourceCodecV2.java | 18 +-- .../common/server/bo/stat/DataSourceBo.java | 16 +-- .../bo/codec/stat/TestAgentStatFactory.java | 2 +- .../codec/stat/v2/DataSourceCodecV2Test.java | 2 +- .../jdbc/cubrid/CubridJdbcUrlParser.java | 66 ++++++--- .../plugin/jdbc/cubrid/CubridPlugin.java | 9 +- .../CubridConnectionStringParserTest.java | 56 ++++++-- .../commons/dbcp/DbcpDataSourceMonitor.java | 5 - .../commons/dbcp2/Dbcp2DataSourceMonitor.java | 5 - .../plugin/jdbc/jtds/JtdsJdbcUrlParser.java | 45 ++++-- .../pinpoint/plugin/jdbc/jtds/JtdsPlugin.java | 12 +- .../jdbc/jtds/JtdsJdbcUrlParserTest.java | 40 ++++-- .../jdbc/mariadb/MariaDBJdbcUrlParser.java | 112 ++++++++++++--- .../plugin/jdbc/mariadb/MariaDBPlugin.java | 18 ++- .../jdbc/mariadb/MariaDBUrlParserTest.java | 35 ++++- .../plugin/jdbc/mysql/MySqlJdbcUrlParser.java | 79 ++++++++--- .../plugin/jdbc/mysql/MySqlPlugin.java | 10 +- .../plugin/jdbc/mysql/MySqlUrlParserTest.java | 37 ++++- .../jdbc/oracle/OracleJdbcUrlParser.java | 79 ++++++----- .../plugin/jdbc/oracle/OraclePlugin.java | 12 +- .../plugin/jdbc/oracle/JDBCUrlParserTest.java | 29 +++- .../postgresql/PostgreSqlJdbcUrlParser.java | 57 ++++++-- .../jdbc/postgresql/PostgreSqlPlugin.java | 11 +- .../postgresql/PostgreSqlUrlParserTest.java | 37 ++++- .../test/MockPluginContextLoadResult.java | 7 + .../test/MockTraceContextFactory.java | 9 +- .../test/monitor/AgentStatMonitorTest.java | 7 +- .../context/ApplicationContextModule.java | 16 ++- ...aultJdbcConnectionStringParserContext.java | 133 ++++++++++++++++++ .../profiler/context/DefaultTraceContext.java | 11 +- .../context/DisabledJdbcUrlParserContext.java | 36 +++++ .../monitor/DataSourceMonitorWrapper.java | 18 --- .../context/monitor/DatabaseInfoLocator.java | 31 ++++ .../JdbcUrlParserContextProvider.java | 50 +++++++ .../DefaultAgentStatCollectorFactory.java | 10 +- .../codahale/MetricMonitorRegistry.java | 6 +- .../datasource/metric/DataSourceGauge.java | 16 ++- .../metric/DataSourceMetricSet.java | 7 +- .../DefaultPluginContextLoadResult.java | 15 ++ .../plugin/DefaultProfilerPluginContext.java | 27 +++- .../DefaultProfilerPluginSetupContext.java | 24 +++- .../plugin/GuardProfilerPluginContext.java | 7 + .../plugin/PluginContextLoadResult.java | 4 + .../pinpoint/profiler/plugin/SetupResult.java | 5 + .../context/MockTraceContextFactory.java | 3 +- .../monitor/DatabaseInfoCacheTest.java | 87 ++++++++++++ .../DefaultPluginMonitorContextTest.java | 5 - .../gc/GarbageCollectorFactoryTest.java | 7 +- .../DefaultDataSourceCollectorTest.java | 21 +-- .../main/resources/pinpoint-web.properties | 3 + .../pinpoint/test/mock/MockTraceContext.java | 8 ++ .../pinpoint/thrift/dto/TDataSource.java | 114 +++++++-------- thrift/src/main/thrift/Pinpoint.thrift | 2 +- .../sampling/sampler/DataSourceSampler.java | 8 +- .../view/DataSourceChartGroupSerializer.java | 2 +- .../web/vo/stat/SampledDataSource.java | 16 +-- .../vo/stat/chart/DataSourceChartGroup.java | 35 +++-- .../main/resources/pinpoint-web.properties | 2 +- .../DataSourceChartGroupSerializerTest.java | 2 +- .../stat/chart/DataSourceChartGroupTest.java | 2 +- 73 files changed, 1424 insertions(+), 387 deletions(-) create mode 100644 bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParser.java create mode 100644 bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParserContext.java create mode 100644 bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor2.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultJdbcConnectionStringParserContext.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisabledJdbcUrlParserContext.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoLocator.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/JdbcUrlParserContextProvider.java create mode 100644 profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoCacheTest.java diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java index 806a919800f8..fef6cacbaf89 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/DatabaseInfo.java @@ -24,6 +24,7 @@ * @author emeroad */ public interface DatabaseInfo { + List getHost(); String getMultipleHost(); @@ -37,4 +38,7 @@ public interface DatabaseInfo { ServiceType getType(); ServiceType getExecuteQueryType(); + + boolean isParsingComplete(); + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java index d48ab2b387e0..cb6937955c82 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/context/TraceContext.java @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.bootstrap.context; import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; import com.navercorp.pinpoint.common.annotations.InterfaceAudience; /** @@ -88,4 +89,6 @@ public interface TraceContext { int getAsyncId(); + JdbcConnectionStringParserContext getJdbcUrlParserContext(); + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPluginSetupContext.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPluginSetupContext.java index 3b94d491af1f..09a071482ae1 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPluginSetupContext.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPluginSetupContext.java @@ -15,6 +15,7 @@ package com.navercorp.pinpoint.bootstrap.plugin; import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; /** * Provides attributes and objects to interceptors. @@ -39,4 +40,6 @@ public interface ProfilerPluginSetupContext { */ void addApplicationTypeDetector(ApplicationTypeDetector... detectors); + void addJdbcConnectionStringParser(JdbcConnectionStringParser jdbcConnectionStringParser); + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/DefaultDatabaseInfo.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/DefaultDatabaseInfo.java index 96be5be8e2a2..caa5aaedf96e 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/DefaultDatabaseInfo.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/DefaultDatabaseInfo.java @@ -26,15 +26,20 @@ */ public class DefaultDatabaseInfo implements DatabaseInfo { - private ServiceType type = ServiceType.UNKNOWN_DB; - private ServiceType executeQueryType = ServiceType.UNKNOWN_DB_EXECUTE_QUERY; - private String databaseId; - private String realUrl; // URL BEFORE refinement - private String normalizedUrl; - private List host; - private String multipleHost; + private final ServiceType type; + private final ServiceType executeQueryType; + private final String databaseId; + private final String realUrl; // URL BEFORE refinement + private final String normalizedUrl; + private final List host; + private final String multipleHost; + private final boolean parsingComplete; public DefaultDatabaseInfo(ServiceType type, ServiceType executeQueryType, String realUrl, String normalizedUrl, List host, String databaseId) { + this(type, executeQueryType, realUrl, normalizedUrl, host, databaseId, true); + } + + public DefaultDatabaseInfo(ServiceType type, ServiceType executeQueryType, String realUrl, String normalizedUrl, List host, String databaseId, boolean parsingComplete) { if (type == null) { throw new NullPointerException("type must not be null"); } @@ -48,6 +53,7 @@ public DefaultDatabaseInfo(ServiceType type, ServiceType executeQueryType, Strin this.host = host; this.multipleHost = merge(host); this.databaseId = databaseId; + this.parsingComplete = parsingComplete; } private String merge(List host) { @@ -101,15 +107,24 @@ public ServiceType getExecuteQueryType() { return executeQueryType; } + @Override + public boolean isParsingComplete() { + return parsingComplete; + } + @Override public String toString() { - return "DatabaseInfo{" + - "type=" + type + - ", executeQueryType=" + executeQueryType + - ", databaseId='" + databaseId + '\'' + - ", realUrl='" + realUrl + '\'' + - ", normalizedUrl='" + normalizedUrl + '\'' + - ", host=" + host + - '}'; + final StringBuilder sb = new StringBuilder("DefaultDatabaseInfo{"); + sb.append("type=").append(type); + sb.append(", executeQueryType=").append(executeQueryType); + sb.append(", databaseId='").append(databaseId).append('\''); + sb.append(", realUrl='").append(realUrl).append('\''); + sb.append(", normalizedUrl='").append(normalizedUrl).append('\''); + sb.append(", host=").append(host); + sb.append(", multipleHost='").append(multipleHost).append('\''); + sb.append(", parsingComplete=").append(parsingComplete); + sb.append('}'); + return sb.toString(); } + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParser.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParser.java new file mode 100644 index 000000000000..348132110c30 --- /dev/null +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParser.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017 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.bootstrap.plugin.jdbc; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +/** + * @author Taejin Koo + */ +public interface JdbcConnectionStringParser { + + DatabaseInfo parse(String url); + + ServiceType getServiceType(); + +} diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParserContext.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParserContext.java new file mode 100644 index 000000000000..04f3de068ce3 --- /dev/null +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcConnectionStringParserContext.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017 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.bootstrap.plugin.jdbc; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +/** + * @author Taejin Koo + */ +public interface JdbcConnectionStringParserContext { + + DatabaseInfo parse(ServiceType serviceType, String jdbcUrl); + +} diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcUrlParser.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcUrlParser.java index 478ee2aad47e..0e85ea0a31b3 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcUrlParser.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/JdbcUrlParser.java @@ -14,17 +14,21 @@ */ package com.navercorp.pinpoint.bootstrap.plugin.jdbc; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; import com.navercorp.pinpoint.bootstrap.logging.PLogger; import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + /** * @author Jongho Moon * */ +/** + * @deprecated Since 1.6.1. Use {@link JdbcConnectionStringParser )} + */ +@Deprecated public abstract class JdbcUrlParser { protected final PLogger logger = PLoggerFactory.getLogger(getClass()); private final ConcurrentMap cache = new ConcurrentHashMap(); @@ -59,4 +63,5 @@ public DatabaseInfo parse(String url) { } protected abstract DatabaseInfo doParse(String url); + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/UnKnownDatabaseInfo.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/UnKnownDatabaseInfo.java index 2d38a6a2852e..6d7f9a33c6a4 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/UnKnownDatabaseInfo.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/UnKnownDatabaseInfo.java @@ -16,12 +16,12 @@ package com.navercorp.pinpoint.bootstrap.plugin.jdbc; -import java.util.ArrayList; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; import com.navercorp.pinpoint.common.trace.ServiceType; +import java.util.ArrayList; +import java.util.List; + /** * @author emeroad */ @@ -31,7 +31,7 @@ public class UnKnownDatabaseInfo { static{ final List urls = new ArrayList(); urls.add("unknown"); - INSTANCE = new DefaultDatabaseInfo(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, "unknown", "unknown", urls, "unknown"); + INSTANCE = new DefaultDatabaseInfo(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, "unknown", "unknown", urls, "unknown", false); } public static DatabaseInfo createUnknownDataBase(String url) { @@ -41,6 +41,7 @@ public static DatabaseInfo createUnknownDataBase(String url) { public static DatabaseInfo createUnknownDataBase(ServiceType type, ServiceType executeQueryType, String url) { List list = new ArrayList(); list.add("error"); - return new DefaultDatabaseInfo(type, executeQueryType, url, url, list, "error"); + return new DefaultDatabaseInfo(type, executeQueryType, url, url, list, "error", false); } + } diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor.java index 8593ab4fd4f0..f817816e3cf3 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor.java @@ -33,6 +33,10 @@ * * @author emeroad */ +/** + * @deprecated Since 1.6.1. Use {@link DriverConnectInterceptor2 )} + */ +@Deprecated @TargetMethod(name="connect", paramTypes={ "java.lang.String", "java.util.Properties" }) public class DriverConnectInterceptor extends SpanEventSimpleAroundInterceptorForPlugin { diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor2.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor2.java new file mode 100644 index 000000000000..73190c508648 --- /dev/null +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/jdbc/interceptor/DriverConnectInterceptor2.java @@ -0,0 +1,111 @@ +/* + * Copyright 2017 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.bootstrap.plugin.jdbc.interceptor; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; +import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder; +import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin; +import com.navercorp.pinpoint.bootstrap.interceptor.annotation.TargetMethod; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DatabaseInfoAccessor; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.bootstrap.util.InterceptorUtils; +import com.navercorp.pinpoint.common.trace.ServiceType; + + +/** + * must be used with ExecutionPolicy.ALWAYS + * + * @author emeroad + */ +@TargetMethod(name="connect", paramTypes={ "java.lang.String", "java.util.Properties" }) +public class DriverConnectInterceptor2 extends SpanEventSimpleAroundInterceptorForPlugin { + + private final ServiceType serviceType; + private final boolean recordConnection; + + public DriverConnectInterceptor2(TraceContext context, MethodDescriptor descriptor, ServiceType serviceType) { + this(context, descriptor, serviceType, true); + } + + public DriverConnectInterceptor2(TraceContext context, MethodDescriptor descriptor, ServiceType serviceType, boolean recordConnection) { + super(context, descriptor); + + this.serviceType = serviceType; + // option for mysql loadbalance only. Destination is recorded at lower implementations. + this.recordConnection = recordConnection; + } + + @Override + protected void logBeforeInterceptor(Object target, Object[] args) { + // Must not log args because it contains a password + logger.beforeInterceptor(target, null); + } + + @Override + protected void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) { + } + + + @Override + protected void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) { + logger.afterInterceptor(target, null, result, throwable); + } + + @Override + protected void prepareAfterTrace(Object target, Object[] args, Object result, Throwable throwable) { + final boolean success = InterceptorUtils.isSuccess(throwable); + // Must not check if current transaction is trace target or not. Connection can be made by other thread. + final String driverUrl = (String) args[0]; + DatabaseInfo databaseInfo = traceContext.getJdbcUrlParserContext().parse(serviceType, driverUrl); + if (success) { + if (recordConnection) { + if (result instanceof DatabaseInfoAccessor) { + ((DatabaseInfoAccessor) result)._$PINPOINT$_setDatabaseInfo(databaseInfo); + } + } + } + } + + @Override + protected void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) { + if (recordConnection) { + DatabaseInfo databaseInfo; + if (result instanceof DatabaseInfoAccessor) { + databaseInfo = ((DatabaseInfoAccessor) result)._$PINPOINT$_getDatabaseInfo(); + } else { + databaseInfo = null; + } + + if (databaseInfo == null) { + databaseInfo = UnKnownDatabaseInfo.INSTANCE; + } + + // Count database connect too because it's very heavy operation + recorder.recordServiceType(databaseInfo.getType()); + recorder.recordEndPoint(databaseInfo.getMultipleHost()); + recorder.recordDestinationId(databaseInfo.getDatabaseId()); + } + final String driverUrl = (String) args[0]; + // Invoking databaseInfo.getRealUrl() here is dangerous. It doesn't return real URL if it's a loadbalance connection. + recorder.recordApiCachedString(methodDescriptor, driverUrl, 0); + + recorder.recordException(throwable); + } + +} diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/monitor/DataSourceMonitor.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/monitor/DataSourceMonitor.java index b29e49aa7970..b93024d9ff8a 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/monitor/DataSourceMonitor.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/monitor/DataSourceMonitor.java @@ -25,8 +25,6 @@ public interface DataSourceMonitor { ServiceType getServiceType(); - String getName(); - String getUrl(); int getActiveConnectionSize(); diff --git a/bootstrap-core/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java b/bootstrap-core/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java index 9508c94850de..310e1fb7db55 100644 --- a/bootstrap-core/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java +++ b/bootstrap-core/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/MockTraceContext.java @@ -24,6 +24,7 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.context.TraceId; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; /** * @author emeroad @@ -160,4 +161,10 @@ public Trace removeTraceObject() { trace = null; return old; } + + @Override + public JdbcConnectionStringParserContext getJdbcUrlParserContext() { + return null; + } + } diff --git a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/stat/DataSourceBoMapper.java b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/stat/DataSourceBoMapper.java index 2590445c50b5..5fb5afbc9da4 100644 --- a/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/stat/DataSourceBoMapper.java +++ b/collector/src/main/java/com/navercorp/pinpoint/collector/mapper/thrift/stat/DataSourceBoMapper.java @@ -32,7 +32,7 @@ public DataSourceBo map(TDataSource dataSource) { DataSourceBo dataSourceBo = new DataSourceBo(); dataSourceBo.setId(dataSource.getId()); dataSourceBo.setServiceTypeCode(dataSource.getServiceTypeCode()); - dataSourceBo.setName(dataSource.getName()); + dataSourceBo.setDatabaseName(dataSource.getDatabaseName()); dataSourceBo.setJdbcUrl(dataSource.getUrl()); dataSourceBo.setActiveConnectionSize(dataSource.getActiveConnectionSize()); dataSourceBo.setMaxConnectionSize(dataSource.getMaxConnectionSize()); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2.java index 4ec997b86a6d..8ccb0c3ce5ed 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2.java @@ -93,7 +93,7 @@ private void encodeDataSourceListBo(Buffer valueBuffer, DataSourceListBo dataSou UnsignedIntegerEncodingStrategy.Analyzer.Builder idAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); UnsignedShortEncodingStrategy.Analyzer.Builder serviceTypeAnalyzerBuilder = new UnsignedShortEncodingStrategy.Analyzer.Builder(); - StringEncodingStrategy.Analyzer.Builder nameAnalyzerBuilder = new StringEncodingStrategy.Analyzer.Builder(); + StringEncodingStrategy.Analyzer.Builder databaseNameAnalyzerBuilder = new StringEncodingStrategy.Analyzer.Builder(); StringEncodingStrategy.Analyzer.Builder jdbcUrlAnalyzerBuilder = new StringEncodingStrategy.Analyzer.Builder(); UnsignedIntegerEncodingStrategy.Analyzer.Builder activeConnectionSizeAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); UnsignedIntegerEncodingStrategy.Analyzer.Builder maxConnectionSizeAnalyzerBuilder = new UnsignedIntegerEncodingStrategy.Analyzer.Builder(); @@ -104,7 +104,7 @@ private void encodeDataSourceListBo(Buffer valueBuffer, DataSourceListBo dataSou idAnalyzerBuilder.addValue(dataSourceBo.getId()); serviceTypeAnalyzerBuilder.addValue(dataSourceBo.getServiceTypeCode()); - nameAnalyzerBuilder.addValue(dataSourceBo.getName()); + databaseNameAnalyzerBuilder.addValue(dataSourceBo.getDatabaseName()); jdbcUrlAnalyzerBuilder.addValue(dataSourceBo.getJdbcUrl()); activeConnectionSizeAnalyzerBuilder.addValue(dataSourceBo.getActiveConnectionSize()); maxConnectionSizeAnalyzerBuilder.addValue(dataSourceBo.getMaxConnectionSize()); @@ -112,19 +112,19 @@ private void encodeDataSourceListBo(Buffer valueBuffer, DataSourceListBo dataSou this.codec.encodeValues(valueBuffer, UnsignedLongEncodingStrategy.REPEAT_COUNT, startTimestamps); this.codec.encodeTimestamps(valueBuffer, timestamps); this.encodeDataPoints(valueBuffer, idAnalyzerBuilder.build(), serviceTypeAnalyzerBuilder.build(), - nameAnalyzerBuilder.build(), jdbcUrlAnalyzerBuilder.build(), + databaseNameAnalyzerBuilder.build(), jdbcUrlAnalyzerBuilder.build(), activeConnectionSizeAnalyzerBuilder.build(), maxConnectionSizeAnalyzerBuilder.build()); } private void encodeDataPoints(Buffer valueBuffer, StrategyAnalyzer idAnalyzerBuilder, StrategyAnalyzer serviceTypeAnalyzerBuilder, - StrategyAnalyzer nameAnalyzerBuilder, StrategyAnalyzer jdbcUrlAnalyzerBuilder, + StrategyAnalyzer databaseNameAnalyzerBuilder, StrategyAnalyzer jdbcUrlAnalyzerBuilder, StrategyAnalyzer activeConnectionSizeAnalyzerBuilder, StrategyAnalyzer maxConnectionSizeAnalyzerBuilder) { // encode header AgentStatHeaderEncoder headerEncoder = new BitCountingHeaderEncoder(); headerEncoder.addCode(idAnalyzerBuilder.getBestStrategy().getCode()); headerEncoder.addCode(serviceTypeAnalyzerBuilder.getBestStrategy().getCode()); - headerEncoder.addCode(nameAnalyzerBuilder.getBestStrategy().getCode()); + headerEncoder.addCode(databaseNameAnalyzerBuilder.getBestStrategy().getCode()); headerEncoder.addCode(jdbcUrlAnalyzerBuilder.getBestStrategy().getCode()); headerEncoder.addCode(activeConnectionSizeAnalyzerBuilder.getBestStrategy().getCode()); headerEncoder.addCode(maxConnectionSizeAnalyzerBuilder.getBestStrategy().getCode()); @@ -135,7 +135,7 @@ private void encodeDataPoints(Buffer valueBuffer, StrategyAnalyzer idAn // encode values this.codec.encodeValues(valueBuffer, idAnalyzerBuilder.getBestStrategy(), idAnalyzerBuilder.getValues()); this.codec.encodeValues(valueBuffer, serviceTypeAnalyzerBuilder.getBestStrategy(), serviceTypeAnalyzerBuilder.getValues()); - this.codec.encodeValues(valueBuffer, nameAnalyzerBuilder.getBestStrategy(), nameAnalyzerBuilder.getValues()); + this.codec.encodeValues(valueBuffer, databaseNameAnalyzerBuilder.getBestStrategy(), databaseNameAnalyzerBuilder.getValues()); this.codec.encodeValues(valueBuffer, jdbcUrlAnalyzerBuilder.getBestStrategy(), jdbcUrlAnalyzerBuilder.getValues()); this.codec.encodeValues(valueBuffer, activeConnectionSizeAnalyzerBuilder.getBestStrategy(), activeConnectionSizeAnalyzerBuilder.getValues()); this.codec.encodeValues(valueBuffer, maxConnectionSizeAnalyzerBuilder.getBestStrategy(), maxConnectionSizeAnalyzerBuilder.getValues()); @@ -170,14 +170,14 @@ private DataSourceListBo decodeValue(Buffer valueBuffer, AgentStatDecodingContex EncodingStrategy idEncodingStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy serviceTypeEncodingStrategy = UnsignedShortEncodingStrategy.getFromCode(headerDecoder.getCode()); - EncodingStrategy nameEncodingStrategy = StringEncodingStrategy.getFromCode(headerDecoder.getCode()); + EncodingStrategy databaseNameEncodingStrategy = StringEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy urlEncodingStrategy = StringEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy activeConnectionSizeStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); EncodingStrategy maxConnectionSizeStrategy = UnsignedIntegerEncodingStrategy.getFromCode(headerDecoder.getCode()); List ids = this.codec.decodeValues(valueBuffer, idEncodingStrategy, numValues); List serviceTypeCodes = this.codec.decodeValues(valueBuffer, serviceTypeEncodingStrategy, numValues); - List names = this.codec.decodeValues(valueBuffer, nameEncodingStrategy, numValues); + List databaseNames = this.codec.decodeValues(valueBuffer, databaseNameEncodingStrategy, numValues); List jdbcUrls = this.codec.decodeValues(valueBuffer, urlEncodingStrategy, numValues); List activeConnectionSizes = this.codec.decodeValues(valueBuffer, activeConnectionSizeStrategy, numValues); List maxConnectionSizes = this.codec.decodeValues(valueBuffer, maxConnectionSizeStrategy, numValues); @@ -197,7 +197,7 @@ private DataSourceListBo decodeValue(Buffer valueBuffer, AgentStatDecodingContex dataSourceBo.setId(ids.get(i)); dataSourceBo.setServiceTypeCode(serviceTypeCodes.get(i)); - dataSourceBo.setName(names.get(i)); + dataSourceBo.setDatabaseName(databaseNames.get(i)); dataSourceBo.setJdbcUrl(jdbcUrls.get(i)); dataSourceBo.setActiveConnectionSize(activeConnectionSizes.get(i)); dataSourceBo.setMaxConnectionSize(maxConnectionSizes.get(i)); diff --git a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/DataSourceBo.java b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/DataSourceBo.java index db9e534d68e3..a9d4fdcc0c17 100644 --- a/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/DataSourceBo.java +++ b/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/stat/DataSourceBo.java @@ -33,7 +33,7 @@ public class DataSourceBo implements AgentStatDataPoint { private int id = UNCOLLECTED_INT_VALUE; private short serviceTypeCode = UNCOLLECTED_SERVICE_TYPE_VALUE.getCode(); - private String name = UNCOLLECTED_STRING_VALUE; + private String databaseName = UNCOLLECTED_STRING_VALUE; private String jdbcUrl = UNCOLLECTED_STRING_VALUE; private int activeConnectionSize = UNCOLLECTED_INT_VALUE; private int maxConnectionSize = UNCOLLECTED_INT_VALUE; @@ -89,12 +89,12 @@ public void setServiceTypeCode(short serviceTypeCode) { this.serviceTypeCode = serviceTypeCode; } - public String getName() { - return name; + public String getDatabaseName() { + return databaseName; } - public void setName(String name) { - this.name = name; + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; } public String getJdbcUrl() { @@ -135,7 +135,7 @@ public boolean equals(Object o) { if (activeConnectionSize != that.activeConnectionSize) return false; if (maxConnectionSize != that.maxConnectionSize) return false; if (agentId != null ? !agentId.equals(that.agentId) : that.agentId != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (databaseName != null ? !databaseName.equals(that.databaseName) : that.databaseName != null) return false; return jdbcUrl != null ? jdbcUrl.equals(that.jdbcUrl) : that.jdbcUrl == null; } @@ -147,7 +147,7 @@ public int hashCode() { result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); result = 31 * result + id; result = 31 * result + (int) serviceTypeCode; - result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (databaseName != null ? databaseName.hashCode() : 0); result = 31 * result + (jdbcUrl != null ? jdbcUrl.hashCode() : 0); result = 31 * result + activeConnectionSize; result = 31 * result + maxConnectionSize; @@ -162,7 +162,7 @@ public String toString() { sb.append(", timestamp=").append(timestamp); sb.append(", id=").append(id); sb.append(", serviceTypeCode=").append(serviceTypeCode); - sb.append(", name='").append(name).append('\''); + sb.append(", databaseName='").append(databaseName).append('\''); sb.append(", jdbcUrl='").append(jdbcUrl).append('\''); sb.append(", activeConnectionSize=").append(activeConnectionSize); sb.append(", maxConnectionSize=").append(maxConnectionSize); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java index cb16881c48ad..38f08ad51bb8 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/TestAgentStatFactory.java @@ -296,7 +296,7 @@ private static DataSourceListBo createDataSourceListBo(String agentId, long star dataSourceBo.setId(id); dataSourceBo.setServiceTypeCode(ServiceType.UNKNOWN.getCode()); - dataSourceBo.setName("name-" + id); + dataSourceBo.setDatabaseName("name-" + id); dataSourceBo.setJdbcUrl("jdbcurl-" + id); dataSourceBo.setActiveConnectionSize(RANDOM.nextInt(maxConnectionSize)); dataSourceBo.setMaxConnectionSize(maxConnectionSize); diff --git a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2Test.java b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2Test.java index 324d5a6bafa7..53f82b9c5e4a 100644 --- a/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2Test.java +++ b/commons-server/src/test/java/com/navercorp/pinpoint/common/server/bo/codec/stat/v2/DataSourceCodecV2Test.java @@ -71,7 +71,7 @@ private void verify(DataSourceBo expected, DataSourceBo actual) { Assert.assertEquals("id", expected.getId(), actual.getId()); Assert.assertEquals("serviceTypeCode", expected.getServiceTypeCode(), actual.getServiceTypeCode()); - Assert.assertEquals("name", expected.getName(), actual.getName()); + Assert.assertEquals("name", expected.getDatabaseName(), actual.getDatabaseName()); Assert.assertEquals("jdbcUrl", expected.getJdbcUrl(), actual.getJdbcUrl()); Assert.assertEquals("activeConnectionSize", expected.getActiveConnectionSize(), actual.getActiveConnectionSize()); Assert.assertEquals("maxConnectionSize", expected.getMaxConnectionSize(), actual.getMaxConnectionSize()); diff --git a/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridJdbcUrlParser.java b/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridJdbcUrlParser.java index 6d083cce4c93..1b5b6c28aaf7 100644 --- a/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridJdbcUrlParser.java +++ b/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridJdbcUrlParser.java @@ -16,39 +16,64 @@ package com.navercorp.pinpoint.plugin.jdbc.cubrid; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author emeroad */ -public class CubridJdbcUrlParser extends JdbcUrlParser { +public class CubridJdbcUrlParser implements JdbcConnectionStringParser { + public static final String DEFAULT_HOSTNAME = "localhost"; public static final int DEFAULT_PORT = 30000; public static final String DEFAULT_USER = "public"; public static final String DEFAULT_PASSWORD = ""; - private static final String URL_PATTERN = "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; + private static final String URL_PREFIX_PATTERN = "jdbc:cubrid(-oracle|-mysql)?:"; + private static final Pattern PREFIX_PATTERN = Pattern.compile(URL_PREFIX_PATTERN, Pattern.CASE_INSENSITIVE); + + private static final String URL_PATTERN = URL_PREFIX_PATTERN + "([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; private static final Pattern PATTERN = Pattern.compile(URL_PATTERN, Pattern.CASE_INSENSITIVE); + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + @Override - public DatabaseInfo doParse(String url) { - if (url == null) { - return UnKnownDatabaseInfo.createUnknownDataBase(CubridConstants.CUBRID, CubridConstants.CUBRID_EXECUTE_QUERY, null); + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; + } + final Matcher matcher = PREFIX_PATTERN.matcher(jdbcUrl); + if (!matcher.find()) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix-pattern:{})", jdbcUrl, URL_PREFIX_PATTERN); + return UnKnownDatabaseInfo.INSTANCE; } - final Matcher matcher = PATTERN.matcher(url); + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl); + } catch (Exception e) { + logger.warn("CubridJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(CubridConstants.CUBRID, CubridConstants.CUBRID_EXECUTE_QUERY, jdbcUrl); + } + return result; + } + + private DatabaseInfo parse0(String jdbcUrl) { + final Matcher matcher = PATTERN.matcher(jdbcUrl); if (!matcher.find()) { - logger.info("Cubrid connectionString parse fail. url:{}", url); - return UnKnownDatabaseInfo.createUnknownDataBase(CubridConstants.CUBRID, CubridConstants.CUBRID_EXECUTE_QUERY, url); + throw new IllegalArgumentException(); } String host = matcher.group(2); @@ -72,7 +97,7 @@ public DatabaseInfo doParse(String url) { try { port = Integer.parseInt(portString); } catch (NumberFormatException e) { - logger.warn("cubrid portString parsing fail. portString:{}, url:{}", portString, url); + logger.warn("cubrid portString parsing fail. portString:{}, url:{}", portString, jdbcUrl); } } @@ -86,7 +111,7 @@ public DatabaseInfo doParse(String url) { // resolvedUrl = "jdbc:cubrid:" + host + ":" + port + ":" + db + ":" + user + ":********:"; - StringMaker maker = new StringMaker(url); + StringMaker maker = new StringMaker(jdbcUrl); String normalizedUrl = maker.clear().before('?').value(); List hostList = new ArrayList(1); @@ -95,10 +120,9 @@ public DatabaseInfo doParse(String url) { // skip alt host - return new DefaultDatabaseInfo(CubridConstants.CUBRID, CubridConstants.CUBRID_EXECUTE_QUERY, url, normalizedUrl, hostList, db); + return new DefaultDatabaseInfo(CubridConstants.CUBRID, CubridConstants.CUBRID_EXECUTE_QUERY, jdbcUrl, normalizedUrl, hostList, db); } - /* private DatabaseInfo parseCubrid(String url) { // jdbc:cubrid:10.20.30.40:12345:pinpoint::: @@ -118,4 +142,10 @@ private DatabaseInfo parseCubrid(String url) { } */ + + @Override + public ServiceType getServiceType() { + return CubridConstants.CUBRID; + } + } diff --git a/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridPlugin.java b/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridPlugin.java index 769b2fe023d5..c908b69e00ed 100644 --- a/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridPlugin.java +++ b/plugins/cubrid-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridPlugin.java @@ -14,8 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.cubrid; -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -27,6 +25,9 @@ import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; import static com.navercorp.pinpoint.common.util.VarArgs.va; @@ -37,6 +38,7 @@ public class CubridPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); private TransformTemplate transformTemplate; + private final JdbcConnectionStringParser jdbcUrlParser = new CubridJdbcUrlParser(); @Override public void setup(ProfilerPluginSetupContext context) { @@ -46,6 +48,7 @@ public void setup(ProfilerPluginSetupContext context) { logger.info("Cubrid plugin is not executed because plugin enable value is false."); return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); addCUBRIDConnectionTransformer(config); addCUBRIDDriverTransformer(); @@ -91,7 +94,7 @@ private void addCUBRIDDriverTransformer() { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", va(new CubridJdbcUrlParser()), CubridConstants.CUBRID_SCOPE, ExecutionPolicy.ALWAYS); + target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", va(CubridConstants.CUBRID), CubridConstants.CUBRID_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/cubrid-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridConnectionStringParserTest.java b/plugins/cubrid-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridConnectionStringParserTest.java index 88c92f1dadee..8e9468fb2f60 100644 --- a/plugins/cubrid-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridConnectionStringParserTest.java +++ b/plugins/cubrid-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/cubrid/CubridConnectionStringParserTest.java @@ -16,27 +16,25 @@ package com.navercorp.pinpoint.plugin.jdbc.cubrid; +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; -import com.navercorp.pinpoint.plugin.jdbc.cubrid.CubridConstants; -import com.navercorp.pinpoint.plugin.jdbc.cubrid.CubridJdbcUrlParser; - /** * @author emeroad */ public class CubridConnectionStringParserTest { - private final JdbcUrlParser parser = new CubridJdbcUrlParser(); + private final JdbcConnectionStringParser parser = new CubridJdbcUrlParser(); @Test - public void testParse() { + public void testParse1() { String cubrid = "jdbc:cubrid:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; DatabaseInfo dbInfo = parser.parse(cubrid); + Assert.assertTrue(dbInfo.isParsingComplete()); Assert.assertEquals(CubridConstants.CUBRID, dbInfo.getType()); Assert.assertEquals("10.99.196.126:34001", dbInfo.getHost().get(0)); @@ -45,8 +43,46 @@ public void testParse() { } @Test - public void testNullParse() { + public void testParse2() { + String cubrid = "jdbc:cubrid-mysql:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; + + DatabaseInfo dbInfo = parser.parse(cubrid); + Assert.assertTrue(dbInfo.isParsingComplete()); + + Assert.assertEquals(CubridConstants.CUBRID, dbInfo.getType()); + Assert.assertEquals("10.99.196.126:34001", dbInfo.getHost().get(0)); + Assert.assertEquals("nrdwapw", dbInfo.getDatabaseId()); + Assert.assertEquals("jdbc:cubrid-mysql:10.99.196.126:34001:nrdwapw:::", dbInfo.getUrl()); + } + + @Test + public void testParse3() { + String cubrid = "jdbc:cubrid-oracle:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; + + DatabaseInfo dbInfo = parser.parse(cubrid); + Assert.assertTrue(dbInfo.isParsingComplete()); + + Assert.assertEquals(CubridConstants.CUBRID, dbInfo.getType()); + Assert.assertEquals("10.99.196.126:34001", dbInfo.getHost().get(0)); + Assert.assertEquals("nrdwapw", dbInfo.getDatabaseId()); + Assert.assertEquals("jdbc:cubrid-oracle:10.99.196.126:34001:nrdwapw:::", dbInfo.getUrl()); + } + + @Test + public void parseFailTest1() { DatabaseInfo dbInfo = parser.parse(null); - Assert.assertEquals(UnKnownDatabaseInfo.INSTANCE, dbInfo); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); } + + @Test + public void parseFailTest2() { + String cubrid = "jdbc:mysql:10.99.196.126:34001:nrdwapw:::?charset=utf-8:"; + DatabaseInfo dbInfo = parser.parse(cubrid); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + } diff --git a/plugins/dbcp/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp/DbcpDataSourceMonitor.java b/plugins/dbcp/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp/DbcpDataSourceMonitor.java index ede194d0979f..86e53f85140c 100644 --- a/plugins/dbcp/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp/DbcpDataSourceMonitor.java +++ b/plugins/dbcp/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp/DbcpDataSourceMonitor.java @@ -37,11 +37,6 @@ public ServiceType getServiceType() { return CommonsDbcpConstants.SERVICE_TYPE; } - @Override - public String getName() { - return null; - } - @Override public String getUrl() { return dataSource.getUrl(); diff --git a/plugins/dbcp2/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp2/Dbcp2DataSourceMonitor.java b/plugins/dbcp2/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp2/Dbcp2DataSourceMonitor.java index 50994142b3a2..bfc9cd09ce58 100644 --- a/plugins/dbcp2/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp2/Dbcp2DataSourceMonitor.java +++ b/plugins/dbcp2/src/main/java/com/navercorp/pinpoint/plugin/commons/dbcp2/Dbcp2DataSourceMonitor.java @@ -37,11 +37,6 @@ public ServiceType getServiceType() { return CommonsDbcp2Constants.SERVICE_TYPE; } - @Override - public String getName() { - return null; - } - @Override public String getUrl() { return dataSource.getUrl(); diff --git a/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParser.java b/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParser.java index 31e91f52326d..ac9aa4031ad4 100644 --- a/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParser.java +++ b/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParser.java @@ -16,34 +16,57 @@ package com.navercorp.pinpoint.plugin.jdbc.jtds; -import java.util.ArrayList; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +import java.util.ArrayList; +import java.util.List; /** * @author emeroad */ -public class JtdsJdbcUrlParser extends JdbcUrlParser { +public class JtdsJdbcUrlParser implements JdbcConnectionStringParser { public static final int DEFAULT_PORT = 1433; + private static final String URL_PREFIX = "jdbc:jtds:sqlserver:"; + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + @Override - public DatabaseInfo doParse(String url) { - if (url == null) { - return UnKnownDatabaseInfo.createUnknownDataBase(JtdsConstants.MSSQL, JtdsConstants.MSSQL_EXECUTE_QUERY, null); + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; + } + if (!jdbcUrl.startsWith(URL_PREFIX)) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix:{})", jdbcUrl, URL_PREFIX); + return UnKnownDatabaseInfo.INSTANCE; } + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl); + } catch (Exception e) { + logger.warn("JtdsJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(JtdsConstants.MSSQL, JtdsConstants.MSSQL_EXECUTE_QUERY, jdbcUrl); + } + return result; + } + + private DatabaseInfo parse0(String url) { // jdbc:jtds:sqlserver://10.xx.xx.xx:1433;DatabaseName=CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3 // jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] // jdbc:jtds:sqlserver://server/db;user=userName;password=password StringMaker maker = new StringMaker(url); - maker.lower().after("jdbc:jtds:sqlserver:"); + maker.lower().after(URL_PREFIX); StringMaker before = maker.after("//").before(';'); final String hostAndPortAndDataBaseString = before.value(); @@ -69,5 +92,9 @@ public DatabaseInfo doParse(String url) { return new DefaultDatabaseInfo(JtdsConstants.MSSQL, JtdsConstants.MSSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); } + @Override + public ServiceType getServiceType() { + return JtdsConstants.MSSQL; + } } diff --git a/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsPlugin.java b/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsPlugin.java index 625af4edfd1f..750a53935893 100644 --- a/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsPlugin.java +++ b/plugins/jtds/src/main/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsPlugin.java @@ -14,8 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.jtds; -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -27,6 +25,9 @@ import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; import static com.navercorp.pinpoint.common.util.VarArgs.va; @@ -35,6 +36,9 @@ */ public class JtdsPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + + private final JdbcConnectionStringParser jdbcUrlParser = new JtdsJdbcUrlParser(); + private TransformTemplate transformTemplate; @Override @@ -46,6 +50,8 @@ public void setup(ProfilerPluginSetupContext context) { return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); + addConnectionTransformer(config); addDriverTransformer(); addPreparedStatementTransformer(config); @@ -92,7 +98,7 @@ private void addDriverTransformer() { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", va(new JtdsJdbcUrlParser()), JtdsConstants.JTDS_SCOPE, ExecutionPolicy.ALWAYS); + target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", va(JtdsConstants.MSSQL), JtdsConstants.JTDS_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/jtds/src/test/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParserTest.java b/plugins/jtds/src/test/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParserTest.java index 8d6bec36dd0d..28aabe34434e 100644 --- a/plugins/jtds/src/test/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParserTest.java +++ b/plugins/jtds/src/test/java/com/navercorp/pinpoint/plugin/jdbc/jtds/JtdsJdbcUrlParserTest.java @@ -17,22 +17,22 @@ package com.navercorp.pinpoint.plugin.jdbc.jtds; +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; -import com.navercorp.pinpoint.plugin.jdbc.jtds.JtdsConstants; -import com.navercorp.pinpoint.plugin.jdbc.jtds.JtdsJdbcUrlParser; - public class JtdsJdbcUrlParserTest { + private final JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); + @Test public void testParse1() throws Exception { // jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] // jdbc:jtds:sqlserver://server/db;user=userName;password=password String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433;DatabaseName=CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); @@ -44,8 +44,8 @@ public void testParse1() throws Exception { @Test public void testParse2() throws Exception { String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT;sendStringParametersAsUnicode=false;useLOBs=false;loginTimeout=3"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); @@ -57,8 +57,8 @@ public void testParse2() throws Exception { @Test public void testParse3() throws Exception { String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); @@ -69,8 +69,8 @@ public void testParse3() throws Exception { @Test public void testParse4() throws Exception { String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); @@ -84,8 +84,8 @@ public void testParse5() throws Exception { // jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] // jdbc:jtds:sqlserver://server/db;user=userName;password=password String url = "jdbc:jtds:sqlserver://10.xx.xx.xx;DatabaseName=CAFECHAT"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx"); @@ -99,8 +99,8 @@ public void testParse6() throws Exception { // jdbc:jtds:sqlserver://server[:port][/database][;property=value[;...]] // jdbc:jtds:sqlserver://server/db;user=userName;password=password String url = "jdbc:jtds:sqlserver://10.xx.xx.xx"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx"); @@ -113,12 +113,30 @@ public void testParse6() throws Exception { @Test public void testParse7() throws Exception { String url = "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT;abc=1;bcd=2"; - JtdsJdbcUrlParser parser = new JtdsJdbcUrlParser(); DatabaseInfo info = parser.parse(url); + Assert.assertTrue(info.isParsingComplete()); Assert.assertEquals(info.getType(), JtdsConstants.MSSQL); Assert.assertEquals(info.getMultipleHost(), "10.xx.xx.xx:1433"); Assert.assertEquals(info.getDatabaseId(), "CAFECHAT"); Assert.assertEquals(info.getUrl(), "jdbc:jtds:sqlserver://10.xx.xx.xx:1433/CAFECHAT"); } + + @Test + public void parseFailTest1() { + DatabaseInfo info = parser.parse(null); + Assert.assertFalse(info.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, info.getType()); + } + + @Test + public void parseFailTest2() { + String url = "jdbc:oracle:sqlserver://10.xx.xx.xx:1433/CAFECHAT;abc=1;bcd=2"; + DatabaseInfo info = parser.parse(url); + Assert.assertFalse(info.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, info.getType()); + } + } \ No newline at end of file diff --git a/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBJdbcUrlParser.java b/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBJdbcUrlParser.java index c1cad77c6acb..daff217afae9 100644 --- a/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBJdbcUrlParser.java +++ b/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBJdbcUrlParser.java @@ -16,35 +16,73 @@ package com.navercorp.pinpoint.plugin.jdbc.mariadb; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * @author dawidmalina */ -public class MariaDBJdbcUrlParser extends JdbcUrlParser { +public class MariaDBJdbcUrlParser implements JdbcConnectionStringParser { + +// jdbc:(mysql|mariadb):[replication:|failover|loadbalance:|aurora:]//[,]/[database>] +// jdbc:mariadb:loadbalance://10.22.33.44:3306,10.22.33.55:3306/MariaDB?characterEncoding=UTF-8 + private static final String URL_PREFIX = "jdbc:mariadb:"; + private static final String LOADBALANCE_URL_PREFIX = URL_PREFIX + "loadbalance:"; + + private static final String MYSQL_URL_PREFIX = "jdbc:mysql:"; + private static final String LOADBALANCE_MYSQL_URL_PREFIX = MYSQL_URL_PREFIX + "loadbalance:"; - // jdbc:mariadb:loadbalance://10.22.33.44:3306,10.22.33.55:3306/MariaDB?characterEncoding=UTF-8 - private static final String JDBC_MARIADB_LOADBALANCE = "jdbc:mariadb:loadbalance:"; + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); @Override - public DatabaseInfo doParse(String url) { - if (isLoadbalanceUrl(url)) { - return parseLoadbalancedUrl(url); + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; } - return parseNormal(url); + + Type type = Type.findType(jdbcUrl); + if (type == null) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix:{}, {})", jdbcUrl, URL_PREFIX, MYSQL_URL_PREFIX); + return UnKnownDatabaseInfo.INSTANCE; + } + + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl, type); + } catch (Exception e) { + logger.warn("MaridDBJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(MariaDBConstants.MARIADB, MariaDBConstants.MARIADB_EXECUTE_QUERY, jdbcUrl); + } + return result; + } + + private DatabaseInfo parse0(String url, Type type) { + if (isLoadbalanceUrl(url, type)) { + return parseLoadbalancedUrl(url, type); + } + return parseNormal(url, type); + } + + private boolean isLoadbalanceUrl(String url, Type type) { + String loadbalanceUrlPrefix = type.getLoadbalanceUrlPrefix(); + return url.regionMatches(true, 0, loadbalanceUrlPrefix, 0, loadbalanceUrlPrefix.length()); } - private DatabaseInfo parseLoadbalancedUrl(String url) { + private DatabaseInfo parseLoadbalancedUrl(String url, Type type) { // jdbc:mariadb://1.2.3.4:5678/test_db StringMaker maker = new StringMaker(url); - maker.after("jdbc:mariadb:"); + maker.after(type.getUrlPrefix()); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -61,14 +99,10 @@ private DatabaseInfo parseLoadbalancedUrl(String url) { normalizedUrl, hostList, databaseId); } - private boolean isLoadbalanceUrl(String url) { - return url.regionMatches(true, 0, JDBC_MARIADB_LOADBALANCE, 0, JDBC_MARIADB_LOADBALANCE.length()); - } - - private DatabaseInfo parseNormal(String url) { + private DatabaseInfo parseNormal(String url, Type type) { // jdbc:mariadb://1.2.3.4:5678/test_db StringMaker maker = new StringMaker(url); - maker.after("jdbc:mariadb:"); + maker.after(type.getUrlPrefix()); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -81,4 +115,42 @@ private DatabaseInfo parseNormal(String url) { return new DefaultDatabaseInfo(MariaDBConstants.MARIADB, MariaDBConstants.MARIADB_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); } + + @Override + public ServiceType getServiceType() { + return MariaDBConstants.MARIADB; + } + + private static enum Type { + MARIA(URL_PREFIX), + MYSQL(MYSQL_URL_PREFIX); + + private final String urlPrefix; + private final String loadbalanceUrlPrefix; + + Type(String urlPrefix) { + this.urlPrefix = urlPrefix; + this.loadbalanceUrlPrefix = urlPrefix + "loadbalance:"; + } + + private String getUrlPrefix() { + return urlPrefix; + } + + private String getLoadbalanceUrlPrefix() { + return urlPrefix + "loadbalance:"; + } + + private static Type findType(String jdbcUrl) { + for (Type type : Type.values()) { + if (jdbcUrl.startsWith(type.urlPrefix)) { + return type; + } + } + + return null; + } + + } + } diff --git a/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBPlugin.java b/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBPlugin.java index 03074c785110..e415956b1246 100644 --- a/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBPlugin.java +++ b/plugins/mariadb-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBPlugin.java @@ -14,10 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.mariadb; -import static com.navercorp.pinpoint.common.util.VarArgs.va; - -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -30,12 +26,20 @@ import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.PreparedStatementBindingMethodFilter; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; + +import static com.navercorp.pinpoint.common.util.VarArgs.va; /** * @author dawidmalina */ public class MariaDBPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + + private final JdbcConnectionStringParser jdbcUrlParser = new MariaDBJdbcUrlParser(); + private TransformTemplate transformTemplate; @Override @@ -47,6 +51,8 @@ public void setup(ProfilerPluginSetupContext context) { return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); + addConnectionTransformer(config); addDriverTransformer(); addPreparedStatementTransformer(config); @@ -121,8 +127,8 @@ public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, Strin target.addField("com.navercorp.pinpoint.bootstrap.plugin.jdbc.DatabaseInfoAccessor"); target.addScopedInterceptor( - "com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", - va(new MariaDBJdbcUrlParser(), true), MariaDBConstants.MARIADB_SCOPE, ExecutionPolicy.ALWAYS); + "com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", + va(MariaDBConstants.MARIADB, true), MariaDBConstants.MARIADB_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/mariadb-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBUrlParserTest.java b/plugins/mariadb-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBUrlParserTest.java index e31e0f8436b8..1fe23a21afa8 100644 --- a/plugins/mariadb-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBUrlParserTest.java +++ b/plugins/mariadb-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mariadb/MariaDBUrlParserTest.java @@ -16,13 +16,13 @@ package com.navercorp.pinpoint.plugin.jdbc.mariadb; +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; - /** * @author dawidmalina */ @@ -35,6 +35,8 @@ public class MariaDBUrlParserTest { public void mariadbParse1() { DatabaseInfo dbInfo = jdbcUrlParser .parse("jdbc:mariadb://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); @@ -45,6 +47,8 @@ public void mariadbParse1() { public void mariadbParse_mysql() { DatabaseInfo dbInfo = jdbcUrlParser .parse("jdbc:mysql://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); @@ -54,6 +58,8 @@ public void mariadbParse_mysql() { @Test public void mariadbParse2() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mariadb://10.98.133.22:3306/test_lucy_db"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), "10.98.133.22:3306"); Assert.assertEquals(dbInfo.getDatabaseId(), "test_lucy_db"); @@ -66,6 +72,8 @@ public void mariadbParse2() { public void mariadbParse3() { DatabaseInfo dbInfo = jdbcUrlParser .parse("jdbc:mariadb://61.74.71.31/log?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), "61.74.71.31"); Assert.assertEquals(dbInfo.getDatabaseId(), "log"); @@ -77,6 +85,8 @@ public void mariadbParse3() { public void mariadbParseCookierunMaster() { DatabaseInfo dbInfo = jdbcUrlParser.parse( "jdbc:mariadb://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), "10.115.8.209:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -88,6 +98,8 @@ public void mariadbParseCookierunMaster() { public void mariadbParseCookierunSlave() { DatabaseInfo dbInfo = jdbcUrlParser.parse( "jdbc:mariadb:loadbalance://10.118.222.35:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -99,6 +111,8 @@ public void mariadbParseCookierunSlave() { public void mariadbParseCookierunSlave2() { DatabaseInfo dbInfo = jdbcUrlParser.parse( "jdbc:mariadb:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MariaDBConstants.MARIADB); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getHost().get(1), "10.118.222.36:5605"); @@ -107,4 +121,21 @@ public void mariadbParseCookierunSlave2() { "jdbc:mariadb:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun"); logger.info(dbInfo.toString()); } + + @Test + public void parseFailTest1() { + DatabaseInfo dbInfo = jdbcUrlParser.parse(null); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + + @Test + public void parseFailTest2() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + } diff --git a/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlJdbcUrlParser.java b/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlJdbcUrlParser.java index 6ad9b62e04c5..632668edbc65 100644 --- a/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlJdbcUrlParser.java +++ b/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlJdbcUrlParser.java @@ -16,35 +16,66 @@ package com.navercorp.pinpoint.plugin.jdbc.mysql; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * @author emeroad */ -public class MySqlJdbcUrlParser extends JdbcUrlParser { +public class MySqlJdbcUrlParser implements JdbcConnectionStringParser { + private static final String URL_PREFIX = "jdbc:mysql:"; // jdbc:mysql:loadbalance://10.22.33.44:3306,10.22.33.55:3306/MySQL?characterEncoding=UTF-8 - private static final String JDBC_MYSQL_LOADBALANCE = "jdbc:mysql:loadbalance:"; + private static final String LOADBALANCE_URL_PREFIX = URL_PREFIX + "loadbalance:"; + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); @Override - public DatabaseInfo doParse(String url) { - if (isLoadbalanceUrl(url)) { - return parseLoadbalancedUrl(url); + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; + } + if (!jdbcUrl.startsWith(URL_PREFIX)) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix:{})", jdbcUrl, URL_PREFIX); + return UnKnownDatabaseInfo.INSTANCE; + } + + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl); + } catch (Exception e) { + logger.warn("MySqlJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(MySqlConstants.MYSQL, MySqlConstants.MYSQL_EXECUTE_QUERY, jdbcUrl); } - return parseNormal(url); + return result; } - private DatabaseInfo parseLoadbalancedUrl(String url) { + private DatabaseInfo parse0(String jdbcUrl) { + if (isLoadbalanceUrl(jdbcUrl)) { + return parseLoadbalancedUrl(jdbcUrl); + } + return parseNormal(jdbcUrl); + } + + private boolean isLoadbalanceUrl(String jdbcUrl) { + return jdbcUrl.regionMatches(true, 0, LOADBALANCE_URL_PREFIX, 0, LOADBALANCE_URL_PREFIX.length()); + } + + private DatabaseInfo parseLoadbalancedUrl(String jdbcUrl) { // jdbc:mysql://1.2.3.4:5678/test_db - StringMaker maker = new StringMaker(url); - maker.after("jdbc:mysql:"); + StringMaker maker = new StringMaker(jdbcUrl); + maker.after(URL_PREFIX); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -57,17 +88,13 @@ private DatabaseInfo parseLoadbalancedUrl(String url) { String databaseId = maker.next().afterLast('/').before('?').value(); String normalizedUrl = maker.clear().before('?').value(); - return new DefaultDatabaseInfo(MySqlConstants.MYSQL, MySqlConstants.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + return new DefaultDatabaseInfo(MySqlConstants.MYSQL, MySqlConstants.MYSQL_EXECUTE_QUERY, jdbcUrl, normalizedUrl, hostList, databaseId); } - private boolean isLoadbalanceUrl(String url) { - return url.regionMatches(true, 0, JDBC_MYSQL_LOADBALANCE, 0, JDBC_MYSQL_LOADBALANCE.length()); - } - - private DatabaseInfo parseNormal(String url) { + private DatabaseInfo parseNormal(String jdbcUrl) { // jdbc:mysql://1.2.3.4:5678/test_db - StringMaker maker = new StringMaker(url); - maker.after("jdbc:mysql:"); + StringMaker maker = new StringMaker(jdbcUrl); + maker.after(URL_PREFIX); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -77,6 +104,12 @@ private DatabaseInfo parseNormal(String url) { String databaseId = maker.next().afterLast('/').before('?').value(); String normalizedUrl = maker.clear().before('?').value(); - return new DefaultDatabaseInfo(MySqlConstants.MYSQL, MySqlConstants.MYSQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); + return new DefaultDatabaseInfo(MySqlConstants.MYSQL, MySqlConstants.MYSQL_EXECUTE_QUERY, jdbcUrl, normalizedUrl, hostList, databaseId); } + + @Override + public ServiceType getServiceType() { + return MySqlConstants.MYSQL; + } + } diff --git a/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlPlugin.java b/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlPlugin.java index 1c021a774222..cfca24dfe3eb 100644 --- a/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlPlugin.java +++ b/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlPlugin.java @@ -14,8 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.mysql; -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -28,6 +26,9 @@ import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.PreparedStatementBindingMethodFilter; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; import static com.navercorp.pinpoint.common.util.VarArgs.va; @@ -37,6 +38,7 @@ public class MySqlPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); private TransformTemplate transformTemplate; + private final JdbcConnectionStringParser jdbcUrlParser = new MySqlJdbcUrlParser(); @Override public void setup(ProfilerPluginSetupContext context) { @@ -47,6 +49,8 @@ public void setup(ProfilerPluginSetupContext context) { return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); + addConnectionTransformer(config); addDriverTransformer(); addStatementTransformer(); @@ -104,7 +108,7 @@ private void addDriverTransformer() { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", va(new MySqlJdbcUrlParser(), false), MySqlConstants.MYSQL_SCOPE, ExecutionPolicy.ALWAYS); + target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", va(MySqlConstants.MYSQL, false), MySqlConstants.MYSQL_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/mysql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlUrlParserTest.java b/plugins/mysql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlUrlParserTest.java index 099d7833b32a..4c79e8dd327c 100644 --- a/plugins/mysql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlUrlParserTest.java +++ b/plugins/mysql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlUrlParserTest.java @@ -16,14 +16,14 @@ package com.navercorp.pinpoint.plugin.jdbc.mysql; -import java.net.URI; - +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import java.net.URI; /** * @author emeroad @@ -56,8 +56,9 @@ public void testURIParse() throws Exception { @Test public void mysqlParse1() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); @@ -66,8 +67,9 @@ public void mysqlParse1() { @Test public void mysqlParse2() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.98.133.22:3306/test_lucy_db"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.98.133.22:3306"); @@ -80,6 +82,8 @@ public void mysqlParse2() { @Test public void mysqlParse3() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://61.74.71.31/log?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), "61.74.71.31"); Assert.assertEquals(dbInfo.getDatabaseId(), "log"); @@ -90,6 +94,8 @@ public void mysqlParse3() { @Test public void mysqlParseCookierunMaster() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.115.8.209:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -101,6 +107,8 @@ public void mysqlParseCookierunMaster() { @Test public void mysqlParseCookierunSlave() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -111,6 +119,8 @@ public void mysqlParseCookierunSlave() { @Test public void mysqlParseCookierunSlave2() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), MySqlConstants.MYSQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getHost().get(1), "10.118.222.36:5605"); @@ -118,4 +128,21 @@ public void mysqlParseCookierunSlave2() { Assert.assertEquals(dbInfo.getUrl(), "jdbc:mysql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun"); logger.info(dbInfo.toString()); } + + @Test + public void parseFailTest1() { + DatabaseInfo dbInfo = jdbcUrlParser.parse(null); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + + @Test + public void parseFailTest2() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + } diff --git a/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OracleJdbcUrlParser.java b/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OracleJdbcUrlParser.java index 4613622c6c00..8630368b6594 100644 --- a/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OracleJdbcUrlParser.java +++ b/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OracleJdbcUrlParser.java @@ -16,41 +16,62 @@ package com.navercorp.pinpoint.plugin.jdbc.oracle; -import java.util.ArrayList; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; import com.navercorp.pinpoint.bootstrap.logging.PLogger; import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.Description; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.KeyValue; -import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.OracleConnectionStringException; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.OracleNetConnectionDescriptorParser; +import java.util.ArrayList; +import java.util.List; + /** * @author emeroad */ -public class OracleJdbcUrlParser extends JdbcUrlParser { +public class OracleJdbcUrlParser implements JdbcConnectionStringParser { + + private static final String URL_PREFIX = "jdbc:oracle:"; private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); @Override - public DatabaseInfo doParse(String url) { - StringMaker maker = new StringMaker(url); - maker.after("jdbc:oracle:").after(":"); + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; + } + if (!jdbcUrl.startsWith(URL_PREFIX)) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix:{})", jdbcUrl, URL_PREFIX); + return UnKnownDatabaseInfo.INSTANCE; + } + + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl); + } catch (Exception e) { + logger.warn("OracleJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, jdbcUrl); + } + return result; + } + + private DatabaseInfo parse0(String jdbcUrl) { + StringMaker maker = new StringMaker(jdbcUrl); + maker.after(URL_PREFIX).after(":"); String description = maker.after('@').value().trim(); if (description.startsWith("(")) { - return parseNetConnectionUrl(url); + return parseNetConnectionUrl(jdbcUrl); } else { - return parseSimpleUrl(url, maker); + return parseSimpleUrl(jdbcUrl, maker); } } - // rac url. // jdbc:oracle:thin:@(Description=(LOAD_BALANCE=on)" + // "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + @@ -60,10 +81,10 @@ public DatabaseInfo doParse(String url) { // thin driver url // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; - + // With proper indentation and line break, - -// jdbc:oracle:thin: + + // jdbc:oracle:thin: // @( // Description=(LOAD_BALANCE=on) // ( @@ -77,24 +98,12 @@ public DatabaseInfo doParse(String url) { // ) // ) private DatabaseInfo parseNetConnectionUrl(String url) { - try { - // oracle new URL : for rac - OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(url); - KeyValue keyValue = parser.parse(); - // TODO Need to handle oci driver. It's more popular. + // oracle new URL : for rac + OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(url); + KeyValue keyValue = parser.parse(); + // TODO Need to handle oci driver. It's more popular. // parser.getDriverType(); - return createOracleDatabaseInfo(keyValue, url); - } catch (OracleConnectionStringException ex) { - logger.warn("OracleConnectionString parse error. url: " + url + " Caused: " + ex.getMessage(), ex); - - // Log error and just create unknownDataBase - return UnKnownDatabaseInfo.createUnknownDataBase(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, url); - } catch (Throwable ex) { - // If we throw exception more precisely later, catch OracleConnectionStringException only. - logger.warn("OracleConnectionString parse error. url: " + url + " Caused: " + ex.getMessage(), ex); - // Log error and just create unknownDataBase - return UnKnownDatabaseInfo.createUnknownDataBase(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, url); - } + return createOracleDatabaseInfo(keyValue, url); } private DefaultDatabaseInfo parseSimpleUrl(String url, StringMaker maker) { @@ -112,11 +121,15 @@ private DefaultDatabaseInfo parseSimpleUrl(String url, StringMaker maker) { } private DatabaseInfo createOracleDatabaseInfo(KeyValue keyValue, String url) { - Description description = new Description(keyValue); List jdbcHost = description.getJdbcHost(); return new DefaultDatabaseInfo(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, url, url, jdbcHost, description.getDatabaseId()); + } + @Override + public ServiceType getServiceType() { + return OracleConstants.ORACLE; } + } diff --git a/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OraclePlugin.java b/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OraclePlugin.java index f5180c50855d..98582f61dcac 100644 --- a/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OraclePlugin.java +++ b/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/OraclePlugin.java @@ -14,8 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.oracle; -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -27,6 +25,9 @@ import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; import static com.navercorp.pinpoint.common.util.VarArgs.va; @@ -45,6 +46,8 @@ public class OraclePlugin implements ProfilerPlugin, TransformTemplateAware { private TransformTemplate transformTemplate; + private final JdbcConnectionStringParser jdbcUrlParser = new OracleJdbcUrlParser(); + @Override public void setup(ProfilerPluginSetupContext context) { OracleConfig config = new OracleConfig(context.getConfig()); @@ -54,6 +57,8 @@ public void setup(ProfilerPluginSetupContext context) { return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); + addConnectionTransformer(config); addDriverTransformer(); addPreparedStatementTransformer(config); @@ -61,7 +66,6 @@ public void setup(ProfilerPluginSetupContext context) { addStatementTransformer(); } - private void addConnectionTransformer(final OracleConfig config) { transformTemplate.transform("oracle.jdbc.driver.PhysicalConnection", new TransformCallback() { @@ -99,7 +103,7 @@ private void addDriverTransformer() { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", va(new OracleJdbcUrlParser()), OracleConstants.ORACLE_SCOPE, ExecutionPolicy.ALWAYS); + target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", va(OracleConstants.ORACLE), OracleConstants.ORACLE_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/oracle-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/oracle/JDBCUrlParserTest.java b/plugins/oracle-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/oracle/JDBCUrlParserTest.java index ca810da992eb..35625d7a8828 100644 --- a/plugins/oracle-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/oracle/JDBCUrlParserTest.java +++ b/plugins/oracle-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/oracle/JDBCUrlParserTest.java @@ -16,14 +16,14 @@ package com.navercorp.pinpoint.plugin.jdbc.oracle; -import java.net.URI; - +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import java.net.URI; /** * @author emeroad @@ -59,6 +59,8 @@ public void oracleParser1() { // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port:SID"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), OracleConstants.ORACLE); Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); Assert.assertEquals(dbInfo.getDatabaseId(), "SID"); @@ -71,6 +73,8 @@ public void oracleParser2() { // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), OracleConstants.ORACLE); Assert.assertEquals(dbInfo.getHost().get(0), "localhost:1521"); Assert.assertEquals(dbInfo.getDatabaseId(), "XE"); @@ -83,6 +87,8 @@ public void oracleParserServiceName() { // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:oracle:thin:@hostname:port/serviceName"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), OracleConstants.ORACLE); Assert.assertEquals(dbInfo.getHost().get(0), "hostname:port"); Assert.assertEquals(dbInfo.getDatabaseId(), "serviceName"); @@ -101,6 +107,8 @@ public void oracleRacParser1() { "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1522))" + "(CONNECT_DATA=(SERVICE_NAME=service)))"; DatabaseInfo dbInfo = jdbcUrlParser.parse(rac); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), OracleConstants.ORACLE); Assert.assertEquals(dbInfo.getHost().get(0), "1.2.3.4:1521"); Assert.assertEquals(dbInfo.getHost().get(1), "1.2.3.5:1522"); @@ -110,6 +118,21 @@ public void oracleRacParser1() { logger.info(dbInfo.toString()); } + @Test + public void parseFailTest1() { + DatabaseInfo dbInfo = jdbcUrlParser.parse(null); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + + @Test + public void parseFailTest2() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql:thin:@hostname:port:SID"); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } } diff --git a/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlJdbcUrlParser.java b/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlJdbcUrlParser.java index 2a318edfb88c..94de9d08f4b8 100644 --- a/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlJdbcUrlParser.java +++ b/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlJdbcUrlParser.java @@ -16,25 +16,52 @@ package com.navercorp.pinpoint.plugin.jdbc.postgresql; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.logging.PLogger; +import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; -import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * @author Brad Hong */ -public class PostgreSqlJdbcUrlParser extends JdbcUrlParser { +public class PostgreSqlJdbcUrlParser implements JdbcConnectionStringParser { + private static final String URL_PREFIX = "jdbc:postgresql:"; // jdbc:postgresql:loadbalance://10.22.33.44:3306,10.22.33.55:3306/PostgreSQL?characterEncoding=UTF-8 - private static final String JDBC_POSTGRESQL_LOADBALANCE = "jdbc:postgresql:loadbalance:"; + private static final String LOADBALANCE_URL_PREFIX = URL_PREFIX + "loadbalance:"; + + private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); @Override - public DatabaseInfo doParse(String url) { + public DatabaseInfo parse(String jdbcUrl) { + if (jdbcUrl == null) { + logger.warn("jdbcUrl may not be null"); + return UnKnownDatabaseInfo.INSTANCE; + } + if (!jdbcUrl.startsWith(URL_PREFIX)) { + logger.warn("jdbcUrl has invalid prefix.(url:{}, prefix:{})", jdbcUrl, URL_PREFIX); + return UnKnownDatabaseInfo.INSTANCE; + } + + DatabaseInfo result = null; + try { + result = parse0(jdbcUrl); + } catch (Exception e) { + logger.warn("PostgreJdbcUrl parse error. url: " + jdbcUrl + " Caused: " + e.getMessage(), e); + result = UnKnownDatabaseInfo.createUnknownDataBase(PostgreSqlConstants.POSTGRESQL, PostgreSqlConstants.POSTGRESQL_EXECUTE_QUERY, jdbcUrl); + } + return result; + } + + private DatabaseInfo parse0(String url) { if (isLoadbalanceUrl(url)) { return parseLoadbalancedUrl(url); } @@ -44,7 +71,7 @@ public DatabaseInfo doParse(String url) { private DatabaseInfo parseLoadbalancedUrl(String url) { // jdbc:postgresql://1.2.3.4:5678/test_db StringMaker maker = new StringMaker(url); - maker.after("jdbc:postgresql:"); + maker.after(URL_PREFIX); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -56,18 +83,18 @@ private DatabaseInfo parseLoadbalancedUrl(String url) { String databaseId = maker.next().afterLast('/').before('?').value(); String normalizedUrl = maker.clear().before('?').value(); - + return new DefaultDatabaseInfo(PostgreSqlConstants.POSTGRESQL, PostgreSqlConstants.POSTGRESQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); } private boolean isLoadbalanceUrl(String url) { - return url.regionMatches(true, 0, JDBC_POSTGRESQL_LOADBALANCE, 0, JDBC_POSTGRESQL_LOADBALANCE.length()); + return url.regionMatches(true, 0, LOADBALANCE_URL_PREFIX, 0, LOADBALANCE_URL_PREFIX.length()); } private DatabaseInfo parseNormal(String url) { // jdbc:postgresql://1.2.3.4:5678/test_db StringMaker maker = new StringMaker(url); - maker.after("jdbc:postgresql:"); + maker.after(URL_PREFIX); // 1.2.3.4:5678 In case of replication driver could have multiple values // We have to consider mm db too. String host = maker.after("//").before('/').value(); @@ -79,4 +106,10 @@ private DatabaseInfo parseNormal(String url) { String normalizedUrl = maker.clear().before('?').value(); return new DefaultDatabaseInfo(PostgreSqlConstants.POSTGRESQL, PostgreSqlConstants.POSTGRESQL_EXECUTE_QUERY, url, normalizedUrl, hostList, databaseId); } + + @Override + public ServiceType getServiceType() { + return PostgreSqlConstants.POSTGRESQL; + } + } diff --git a/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlPlugin.java b/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlPlugin.java index 817145aeeaea..0c82977c39be 100644 --- a/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlPlugin.java +++ b/plugins/postgresql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlPlugin.java @@ -14,8 +14,6 @@ */ package com.navercorp.pinpoint.plugin.jdbc.postgresql; -import java.security.ProtectionDomain; - import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.Instrumentor; @@ -28,6 +26,9 @@ import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.PreparedStatementBindingMethodFilter; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.security.ProtectionDomain; import static com.navercorp.pinpoint.common.util.VarArgs.va; @@ -38,6 +39,8 @@ public class PostgreSqlPlugin implements ProfilerPlugin, TransformTemplateAware { private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); + private final JdbcConnectionStringParser jdbcUrlParser = new PostgreSqlJdbcUrlParser(); + private TransformTemplate transformTemplate; @Override @@ -49,6 +52,8 @@ public void setup(ProfilerPluginSetupContext context) { return; } + context.addJdbcConnectionStringParser(jdbcUrlParser); + addConnectionTransformer(config); addDriverTransformer(); addPreparedStatementTransformer(config); @@ -147,7 +152,7 @@ private void addDriverTransformer() { public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException { InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer); - target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor", va(new PostgreSqlJdbcUrlParser(), false), PostgreSqlConstants.POSTGRESQL_SCOPE, ExecutionPolicy.ALWAYS); + target.addScopedInterceptor("com.navercorp.pinpoint.bootstrap.plugin.jdbc.interceptor.DriverConnectInterceptor2", va(PostgreSqlConstants.POSTGRESQL, false), PostgreSqlConstants.POSTGRESQL_SCOPE, ExecutionPolicy.ALWAYS); return target.toBytecode(); } diff --git a/plugins/postgresql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlUrlParserTest.java b/plugins/postgresql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlUrlParserTest.java index 7306e9eecb54..aa3e81d49cd6 100644 --- a/plugins/postgresql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlUrlParserTest.java +++ b/plugins/postgresql-jdbc/src/test/java/com/navercorp/pinpoint/plugin/jdbc/postgresql/PostgreSqlUrlParserTest.java @@ -16,14 +16,14 @@ package com.navercorp.pinpoint.plugin.jdbc.postgresql; -import java.net.URI; - +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import java.net.URI; /** * @author Brad Hong @@ -56,8 +56,9 @@ public void testURIParse() throws Exception { @Test public void postgresqlParse1() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql://ip_address:3306/database_name?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), ("ip_address:3306")); Assert.assertEquals(dbInfo.getDatabaseId(), "database_name"); @@ -66,8 +67,9 @@ public void postgresqlParse1() { @Test public void postgresqlParse2() { - DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql://10.98.133.22:3306/test_lucy_db"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.98.133.22:3306"); @@ -80,6 +82,8 @@ public void postgresqlParse2() { @Test public void postgresqlParse3() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql://61.74.71.31/log?useUnicode=yes&characterEncoding=UTF-8"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), "61.74.71.31"); Assert.assertEquals(dbInfo.getDatabaseId(), "log"); @@ -90,6 +94,8 @@ public void postgresqlParse3() { @Test public void postgresqlParseCookierunMaster() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.115.8.209:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -101,6 +107,8 @@ public void postgresqlParseCookierunMaster() { @Test public void postgresqlParseCookierunSlave() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql:loadbalance://10.118.222.35:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getDatabaseId(), "db_cookierun"); @@ -111,6 +119,8 @@ public void postgresqlParseCookierunSlave() { @Test public void postgresqlParseCookierunSlave2() { DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:postgresql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-UNCOMMITTED'"); + Assert.assertTrue(dbInfo.isParsingComplete()); + Assert.assertEquals(dbInfo.getType(), PostgreSqlConstants.POSTGRESQL); Assert.assertEquals(dbInfo.getHost().get(0), "10.118.222.35:5605"); Assert.assertEquals(dbInfo.getHost().get(1), "10.118.222.36:5605"); @@ -118,4 +128,21 @@ public void postgresqlParseCookierunSlave2() { Assert.assertEquals(dbInfo.getUrl(), "jdbc:postgresql:loadbalance://10.118.222.35:5605,10.118.222.36:5605/db_cookierun"); logger.info(dbInfo.toString()); } + + @Test + public void parseFailTest1() { + DatabaseInfo dbInfo = jdbcUrlParser.parse(null); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + + @Test + public void parseFailTest2() { + DatabaseInfo dbInfo = jdbcUrlParser.parse("jdbc:mysql://10.115.8.209:5605/db_cookierun?useUnicode=true&characterEncoding=UTF-8&noAccessToProcedureBodies=true&autoDeserialize=true&elideSetAutoCommits=true&sessionVariables=time_zone='%2B09:00',tx_isolation='READ-COMMITTED'"); + Assert.assertFalse(dbInfo.isParsingComplete()); + + Assert.assertEquals(ServiceType.UNKNOWN_DB, dbInfo.getType()); + } + } diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockPluginContextLoadResult.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockPluginContextLoadResult.java index cbc5bb85ade5..f999e1ffbda7 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockPluginContextLoadResult.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockPluginContextLoadResult.java @@ -20,6 +20,7 @@ import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPlugin; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.common.plugin.PluginLoader; import com.navercorp.pinpoint.profiler.context.ApplicationContext; import com.navercorp.pinpoint.profiler.instrument.ClassInjector; @@ -96,4 +97,10 @@ public List getClassFileTransformer() { public List getApplicationTypeDetectorList() { return Collections.emptyList(); } + + @Override + public List getJdbcConnectionStringParserList() { + return Collections.emptyList(); + } + } diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java index cab1171e7ebd..40d72a8f8ca1 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockTraceContextFactory.java @@ -25,19 +25,17 @@ import com.navercorp.pinpoint.profiler.context.DefaultServerMetaDataHolder; import com.navercorp.pinpoint.profiler.context.DefaultTraceContext; import com.navercorp.pinpoint.profiler.context.DefaultTraceFactoryBuilder; +import com.navercorp.pinpoint.profiler.context.DisabledJdbcUrlParserContext; import com.navercorp.pinpoint.profiler.context.IdGenerator; -import com.navercorp.pinpoint.profiler.context.monitor.DefaultPluginMonitorContext; import com.navercorp.pinpoint.profiler.context.TraceFactoryBuilder; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceRepository; +import com.navercorp.pinpoint.profiler.context.monitor.DefaultPluginMonitorContext; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; import com.navercorp.pinpoint.profiler.context.storage.LogStorageFactory; import com.navercorp.pinpoint.profiler.context.storage.StorageFactory; import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataCacheService; -import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataService; import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataCacheService; -import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataService; import com.navercorp.pinpoint.profiler.metadata.StringMetaDataCacheService; -import com.navercorp.pinpoint.profiler.metadata.StringMetaDataService; import com.navercorp.pinpoint.profiler.sampler.SamplerFactory; import com.navercorp.pinpoint.profiler.sender.EnhancedDataSender; import com.navercorp.pinpoint.profiler.sender.LoggingDataSender; @@ -113,7 +111,8 @@ public MockTraceContextFactory(ProfilerConfig profilerConfig) { this.traceContext = new DefaultTraceContext(profilerConfig, agentInformation, traceFactoryBuilder, pluginMonitorContext, serverMetaDataHolder, - apiMetaDataCacheService, stringMetaDataCacheService, sqlMetaDataCacheService + apiMetaDataCacheService, stringMetaDataCacheService, sqlMetaDataCacheService, + DisabledJdbcUrlParserContext.INSTANCE ); } diff --git a/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java b/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java index 2be4b4e81cb7..acc10e151608 100644 --- a/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java +++ b/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java @@ -23,6 +23,7 @@ import com.navercorp.pinpoint.profiler.context.DefaultTransactionCounter; import com.navercorp.pinpoint.profiler.context.TransactionCounter; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceRepository; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.context.monitor.DefaultPluginMonitorContext; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; import com.navercorp.pinpoint.profiler.monitor.AgentStatMonitor; @@ -36,6 +37,7 @@ import com.navercorp.pinpoint.thrift.dto.TAgentStatBatch; import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,6 +54,9 @@ public class AgentStatMonitorTest { private TBaseRecorder tBaseRecorder; private DataSender dataSender; + @Mock + private DatabaseInfoLocator databaseInfoLocator; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -93,7 +98,7 @@ private AgentStatCollectorFactory newAgentStatCollectorFactory() { AtomicIdGenerator idGenerator = new AtomicIdGenerator(); TransactionCounter transactionCounter = new DefaultTransactionCounter(idGenerator); PluginMonitorContext pluginMonitorContext = new DefaultPluginMonitorContext(); - return new DefaultAgentStatCollectorFactory(profilerConfig, activeTraceRepository, transactionCounter, pluginMonitorContext); + return new DefaultAgentStatCollectorFactory(profilerConfig, activeTraceRepository, transactionCounter, pluginMonitorContext, databaseInfoLocator); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ApplicationContextModule.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ApplicationContextModule.java index f6866caa86bd..74a1e8448428 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ApplicationContextModule.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/ApplicationContextModule.java @@ -25,6 +25,7 @@ import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentEngine; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; import com.navercorp.pinpoint.bootstrap.sampler.Sampler; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; import com.navercorp.pinpoint.common.trace.ServiceType; @@ -35,22 +36,24 @@ import com.navercorp.pinpoint.profiler.DynamicTransformerRegistry; import com.navercorp.pinpoint.profiler.JvmInformation; import com.navercorp.pinpoint.profiler.context.module.AgentId; -import com.navercorp.pinpoint.profiler.context.module.ApplicationServerType; import com.navercorp.pinpoint.profiler.context.module.AgentStartTime; import com.navercorp.pinpoint.profiler.context.module.ApplicationName; +import com.navercorp.pinpoint.profiler.context.module.ApplicationServerType; import com.navercorp.pinpoint.profiler.context.module.BootstrapJarPaths; import com.navercorp.pinpoint.profiler.context.module.PluginJars; import com.navercorp.pinpoint.profiler.context.module.SpanDataSender; import com.navercorp.pinpoint.profiler.context.module.StatDataSender; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; import com.navercorp.pinpoint.profiler.context.provider.AgentInfoSenderProvider; import com.navercorp.pinpoint.profiler.context.provider.AgentInformationProvider; -import com.navercorp.pinpoint.profiler.context.provider.ApplicationServerTypeProvider; import com.navercorp.pinpoint.profiler.context.provider.AgentStartTimeProvider; +import com.navercorp.pinpoint.profiler.context.provider.ApplicationServerTypeProvider; import com.navercorp.pinpoint.profiler.context.provider.ClassFileTransformerDispatcherProvider; import com.navercorp.pinpoint.profiler.context.provider.CommandDispatcherProvider; import com.navercorp.pinpoint.profiler.context.provider.DynamicTransformTriggerProvider; import com.navercorp.pinpoint.profiler.context.provider.InstrumentEngineProvider; +import com.navercorp.pinpoint.profiler.context.provider.JdbcUrlParserContextProvider; import com.navercorp.pinpoint.profiler.context.provider.JvmInformationProvider; import com.navercorp.pinpoint.profiler.context.provider.PinpointClientFactoryProvider; import com.navercorp.pinpoint.profiler.context.provider.PinpointClientProvider; @@ -75,7 +78,6 @@ import com.navercorp.pinpoint.profiler.monitor.codahale.AgentStatCollectorFactory; import com.navercorp.pinpoint.profiler.monitor.codahale.DefaultAgentStatCollectorFactory; import com.navercorp.pinpoint.profiler.plugin.PluginContextLoadResult; -import com.navercorp.pinpoint.profiler.plugin.PluginSetup; import com.navercorp.pinpoint.profiler.receiver.CommandDispatcher; import com.navercorp.pinpoint.profiler.sender.DataSender; import com.navercorp.pinpoint.profiler.sender.EnhancedDataSender; @@ -145,6 +147,14 @@ protected void configure() { bind(AgentStatMonitor.class).to(DefaultAgentStatMonitor.class).in(Scopes.SINGLETON); bind(PluginContextLoadResult.class).toProvider(PluginContextLoadResultProvider.class).in(Scopes.SINGLETON); +// bind(DatabaseInfoCache.class).toProvider(DatabaseInfoCacheProvider.class).in(Scopes.SINGLETON); + + bind(DefaultJdbcConnectionStringParserContext.class).toProvider(JdbcUrlParserContextProvider.class).in(Scopes.SINGLETON); + bind(JdbcConnectionStringParserContext.class).to(DefaultJdbcConnectionStringParserContext.class).in(Scopes.SINGLETON); + bind(DatabaseInfoLocator.class).to(DefaultJdbcConnectionStringParserContext.class).in(Scopes.SINGLETON); + + + bind(AgentInformation.class).toProvider(AgentInformationProvider.class).in(Scopes.SINGLETON); bind(JvmInformation.class).toProvider(JvmInformationProvider.class).in(Scopes.SINGLETON); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultJdbcConnectionStringParserContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultJdbcConnectionStringParserContext.java new file mode 100644 index 000000000000..1b27ebedfb00 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultJdbcConnectionStringParserContext.java @@ -0,0 +1,133 @@ +/* + * Copyright 2017 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.profiler.context; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Taejin Koo + */ +public class DefaultJdbcConnectionStringParserContext implements JdbcConnectionStringParserContext, DatabaseInfoLocator { + + private final List jdbcConnectionStringParserList; + + private final ConcurrentHashMap cache = new ConcurrentHashMap(); + private final ConcurrentHashMap eachServiceTypeCache = new ConcurrentHashMap(); + + public DefaultJdbcConnectionStringParserContext(List jdbcConnectionStringParserList) { + this.jdbcConnectionStringParserList = jdbcConnectionStringParserList; + } + + @Override + public DatabaseInfo getDatabaseInfo(String jdbcUrl) { + DatabaseInfo databaseInfo = cache.get(jdbcUrl); + return databaseInfo; + } + + @Override + public DatabaseInfo getDatabaseInfo(ServiceType serviceType, String jdbcUrl) { + CacheKey cacheKey = new CacheKey(serviceType, jdbcUrl); + DatabaseInfo databaseInfo = eachServiceTypeCache.get(cacheKey); + if (databaseInfo != null && databaseInfo.isParsingComplete()) { + return databaseInfo; + } + return null; + } + + @Override + public DatabaseInfo parse(ServiceType serviceType, String jdbcUrl) { + if (jdbcUrl == null) { + return UnKnownDatabaseInfo.INSTANCE; + } + + CacheKey cacheKey = new CacheKey(serviceType, jdbcUrl); + DatabaseInfo cacheValue = eachServiceTypeCache.get(cacheKey); + if (cacheValue != null) { + return cacheValue; + } + + for (JdbcConnectionStringParser parser : jdbcConnectionStringParserList) { + if (serviceType == parser.getServiceType()) { + DatabaseInfo databaseInfo = parser.parse(jdbcUrl); + return putCacheIfAbsent(cacheKey, databaseInfo); + } + } + + return putCacheIfAbsent(cacheKey, UnKnownDatabaseInfo.createUnknownDataBase(jdbcUrl)); + } + + private DatabaseInfo putCacheIfAbsent(CacheKey cacheKey, DatabaseInfo databaseInfo) { + if (databaseInfo.isParsingComplete()) { + cache.putIfAbsent(cacheKey.getJdbcUrl(), databaseInfo); + } + + DatabaseInfo old = eachServiceTypeCache.putIfAbsent(cacheKey, databaseInfo); + if (old != null) { + return old; + } + + return databaseInfo; + } + + private static class CacheKey { + + private final ServiceType serviceType; + private final String jdbcUrl; + + public CacheKey(ServiceType serviceType, String jdbcUrl) { + this.serviceType = serviceType; + this.jdbcUrl = jdbcUrl; + } + + public ServiceType getServiceType() { + return serviceType; + } + + public String getJdbcUrl() { + return jdbcUrl; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CacheKey cacheKey = (CacheKey) o; + + if (serviceType != null ? !serviceType.equals(cacheKey.serviceType) : cacheKey.serviceType != null) return false; + return jdbcUrl != null ? jdbcUrl.equals(cacheKey.jdbcUrl) : cacheKey.jdbcUrl == null; + + } + + @Override + public int hashCode() { + int result = serviceType != null ? serviceType.hashCode() : 0; + result = 31 * result + (jdbcUrl != null ? jdbcUrl.hashCode() : 0); + return result; + } + + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java index cd4e156327d2..240f1343e5db 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTraceContext.java @@ -25,6 +25,7 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.context.TraceId; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; import com.navercorp.pinpoint.common.annotations.InterfaceAudience; import com.navercorp.pinpoint.profiler.AgentInformation; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; @@ -56,6 +57,7 @@ public class DefaultTraceContext implements TraceContext { private final ServerMetaDataHolder serverMetaDataHolder; private final PluginMonitorContext pluginMonitorContext; + private final JdbcConnectionStringParserContext jdbcUrlParserContext; private final AsyncIdGenerator asyncIdGenerator = new AsyncIdGenerator(); @@ -66,7 +68,8 @@ public DefaultTraceContext(ProfilerConfig profilerConfig, final AgentInformation ServerMetaDataHolder serverMetaDataHolder, ApiMetaDataService apiMetaDataService, StringMetaDataService stringMetaDataService, - SqlMetaDataService sqlMetaDataService + SqlMetaDataService sqlMetaDataService, + JdbcConnectionStringParserContext jdbcUrlParserContext ) { if (profilerConfig == null) { throw new NullPointerException("profilerConfig must not be null"); @@ -95,6 +98,7 @@ public DefaultTraceContext(ProfilerConfig profilerConfig, final AgentInformation this.traceFactory = traceFactoryBuilder.build(this); this.pluginMonitorContext = pluginMonitorContext; + this.jdbcUrlParserContext = jdbcUrlParserContext; this.apiMetaDataService = apiMetaDataService; this.stringMetaDataService = stringMetaDataService; @@ -247,4 +251,9 @@ public PluginMonitorContext getPluginMonitorContext() { return pluginMonitorContext; } + @Override + public JdbcConnectionStringParserContext getJdbcUrlParserContext() { + return jdbcUrlParserContext; + } + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisabledJdbcUrlParserContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisabledJdbcUrlParserContext.java new file mode 100644 index 000000000000..0257672f2c99 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisabledJdbcUrlParserContext.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017 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.profiler.context; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +/** + * @author Taejin Koo + */ +public final class DisabledJdbcUrlParserContext implements JdbcConnectionStringParserContext { + + public static final DisabledJdbcUrlParserContext INSTANCE = new DisabledJdbcUrlParserContext(); + + @Override + public DatabaseInfo parse(ServiceType serviceType, String jdbcUrl) { + return UnKnownDatabaseInfo.createUnknownDataBase(jdbcUrl); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DataSourceMonitorWrapper.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DataSourceMonitorWrapper.java index 2a798b72cc69..b0611b9e6100 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DataSourceMonitorWrapper.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DataSourceMonitorWrapper.java @@ -30,7 +30,6 @@ public class DataSourceMonitorWrapper implements PluginMonitorWrapper, DataSourc private final WeakReference monitorReference; private volatile ServiceType serviceType; - private volatile String name; private volatile String url; public DataSourceMonitorWrapper(int id, DataSourceMonitor dataSourceMonitor) { @@ -68,23 +67,6 @@ public ServiceType getServiceType() { return ServiceType.UNKNOWN; } - @Override - public String getName() { - if (this.name != null) { - return this.name; - } - - DataSourceMonitor dataSourceMonitor = getInstance(); - if (dataSourceMonitor != null) { - String name = dataSourceMonitor.getName(); - if (name != null) { - this.name = name; - } - return name; - } - return null; - } - @Override public String getUrl() { if (this.url != null) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoLocator.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoLocator.java new file mode 100644 index 000000000000..d865222c9c0c --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoLocator.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017 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.profiler.context.monitor; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.common.trace.ServiceType; + +/** + * @author Taejin Koo + */ +public interface DatabaseInfoLocator { + + DatabaseInfo getDatabaseInfo(String jdbcUrl); + + DatabaseInfo getDatabaseInfo(ServiceType serviceType, String jdbcUrl); + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/JdbcUrlParserContextProvider.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/JdbcUrlParserContextProvider.java new file mode 100644 index 000000000000..d2d3163c0df7 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/provider/JdbcUrlParserContextProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2017 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.profiler.context.provider; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; +import com.navercorp.pinpoint.profiler.context.DefaultJdbcConnectionStringParserContext; +import com.navercorp.pinpoint.profiler.plugin.PluginContextLoadResult; + +import java.util.List; + +/** + * @author Taejin Koo + */ +public class JdbcUrlParserContextProvider implements Provider { + + private final Provider pluginContextLoadResultProvider; + + @Inject + public JdbcUrlParserContextProvider(Provider pluginContextLoadResultProvider) { + if (pluginContextLoadResultProvider == null) { + throw new NullPointerException("pluginContextLoadResult must not be null"); + } + this.pluginContextLoadResultProvider = pluginContextLoadResultProvider; + } + + @Override + public DefaultJdbcConnectionStringParserContext get() { + PluginContextLoadResult pluginContextLoadResult = this.pluginContextLoadResultProvider.get(); + List jdbcConnectionStringParserList = pluginContextLoadResult.getJdbcConnectionStringParserList(); + + return new DefaultJdbcConnectionStringParserContext(jdbcConnectionStringParserList); + } + +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/DefaultAgentStatCollectorFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/DefaultAgentStatCollectorFactory.java index ba1aa43da516..a55f9f0458e8 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/DefaultAgentStatCollectorFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/DefaultAgentStatCollectorFactory.java @@ -21,6 +21,7 @@ import com.navercorp.pinpoint.profiler.context.TransactionCounter; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceRepository; import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorWrapper; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.context.monitor.DefaultPluginMonitorContext; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorWrapperLocator; @@ -71,7 +72,7 @@ public class DefaultAgentStatCollectorFactory implements AgentStatCollectorFacto private final DataSourceCollector dataSourceCollector; @Inject - public DefaultAgentStatCollectorFactory(ProfilerConfig profilerConfig, ActiveTraceRepository activeTraceRepository, TransactionCounter transactionCounter, PluginMonitorContext pluginMonitorContext) { + public DefaultAgentStatCollectorFactory(ProfilerConfig profilerConfig, ActiveTraceRepository activeTraceRepository, TransactionCounter transactionCounter, PluginMonitorContext pluginMonitorContext, DatabaseInfoLocator databaseInfoLocator) { if (profilerConfig == null) { throw new NullPointerException("profilerConfig must not be null"); } @@ -89,7 +90,7 @@ public DefaultAgentStatCollectorFactory(ProfilerConfig profilerConfig, ActiveTra this.cpuLoadCollector = createCpuLoadCollector(profilerConfig.getProfilerJvmVendorName()); this.transactionMetricCollector = createTransactionMetricCollector(transactionCounter); this.activeTraceMetricCollector = createActiveTraceCollector(activeTraceRepository, profilerConfig.isTraceAgentActiveThread()); - this.dataSourceCollector = createDataSourceCollector(pluginMonitorContext); + this.dataSourceCollector = createDataSourceCollector(pluginMonitorContext, databaseInfoLocator); } private MetricMonitorRegistry createRegistry() { @@ -175,11 +176,12 @@ private ActiveTraceMetricCollector createActiveTraceCollector(ActiveTraceReposit return ActiveTraceMetricCollector.EMPTY_ACTIVE_TRACE_COLLECTOR; } - private DataSourceCollector createDataSourceCollector(PluginMonitorContext pluginMonitorContext) { + private DataSourceCollector createDataSourceCollector(PluginMonitorContext pluginMonitorContext, DatabaseInfoLocator databaseInfoLocator) { if (pluginMonitorContext instanceof DefaultPluginMonitorContext) { PluginMonitorWrapperLocator dataSourceMonitorLocator = ((DefaultPluginMonitorContext) pluginMonitorContext).getDataSourceMonitorLocator(); if (dataSourceMonitorLocator != null) { - DataSourceMetricSet dataSourceMetricSet = this.monitorRegistry.registerDataSourceMonitor(new MonitorName(MetricMonitorValues.DATASOURCE), dataSourceMonitorLocator); + DataSourceMetricSet dataSourceMetricSet = new DataSourceMetricSet(dataSourceMonitorLocator, databaseInfoLocator); + this.monitorRegistry.registerDataSourceMonitor(new MonitorName(MetricMonitorValues.DATASOURCE), dataSourceMetricSet); return new DefaultDataSourceCollector(dataSourceMetricSet); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistry.java index 8087dc59d77e..0d4cb18a2f85 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/MetricMonitorRegistry.java @@ -26,8 +26,6 @@ import com.codahale.metrics.jvm.ThreadStatesGaugeSet; import com.navercorp.pinpoint.profiler.context.TransactionCounter; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceLocator; -import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorWrapper; -import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorWrapperLocator; import com.navercorp.pinpoint.profiler.monitor.CounterMonitor; import com.navercorp.pinpoint.profiler.monitor.EventRateMonitor; import com.navercorp.pinpoint.profiler.monitor.HistogramMonitor; @@ -114,9 +112,9 @@ public ThreadStatesGaugeSet registerJvmThreadStatesMonitor(MonitorName monitorNa return this.delegate.register(monitorName.getName(), new ThreadStatesGaugeSet()); } - public DataSourceMetricSet registerDataSourceMonitor(MonitorName monitorName, PluginMonitorWrapperLocator dataSourceMonitorLocator) { + public DataSourceMetricSet registerDataSourceMonitor(MonitorName monitorName, DataSourceMetricSet dataSourceMetricSet) { validateMonitorName(monitorName); - return this.delegate.register(monitorName.getName(), new DataSourceMetricSet(dataSourceMonitorLocator)); + return this.delegate.register(monitorName.getName(), dataSourceMetricSet); } public MetricRegistry getRegistry() { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceGauge.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceGauge.java index bcd18361bb04..fbb5174b0b8f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceGauge.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceGauge.java @@ -17,7 +17,9 @@ package com.navercorp.pinpoint.profiler.monitor.codahale.datasource.metric; import com.codahale.metrics.Gauge; +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorWrapper; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.thrift.dto.TDataSource; /** @@ -26,9 +28,11 @@ public class DataSourceGauge implements Gauge { private final DataSourceMonitorWrapper dataSourceMonitorWrapper; + private final DatabaseInfoLocator databaseInfoLocator; - protected DataSourceGauge(DataSourceMonitorWrapper dataSourceMonitorWrapper) { + protected DataSourceGauge(DataSourceMonitorWrapper dataSourceMonitorWrapper, DatabaseInfoLocator databaseInfoLocator) { this.dataSourceMonitorWrapper = dataSourceMonitorWrapper; + this.databaseInfoLocator = databaseInfoLocator; } @Override @@ -37,14 +41,14 @@ public TDataSource getValue() { dataSource.setId(dataSourceMonitorWrapper.getId()); dataSource.setServiceTypeCode(dataSourceMonitorWrapper.getServiceType().getCode()); - String name = dataSourceMonitorWrapper.getName(); - if (name != null) { - dataSource.setName(name); - } - String jdbcUrl = dataSourceMonitorWrapper.getUrl(); if (jdbcUrl != null) { dataSource.setUrl(jdbcUrl); + + DatabaseInfo databaseInfo = databaseInfoLocator.getDatabaseInfo(jdbcUrl); + if (databaseInfo != null) { + dataSource.setDatabaseName(databaseInfo.getDatabaseId()); + } } int activeConnectionSize = dataSourceMonitorWrapper.getActiveConnectionSize(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceMetricSet.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceMetricSet.java index 7e455b9710cd..3e09016b1fd6 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceMetricSet.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/codahale/datasource/metric/DataSourceMetricSet.java @@ -19,6 +19,7 @@ import com.codahale.metrics.Metric; import com.codahale.metrics.MetricSet; import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorWrapper; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorWrapperLocator; import com.navercorp.pinpoint.profiler.monitor.codahale.MetricMonitorValues; @@ -32,9 +33,11 @@ public class DataSourceMetricSet implements MetricSet { private final PluginMonitorWrapperLocator dataSourceMonitorLocator; + private final DatabaseInfoLocator databaseInfoLocator; - public DataSourceMetricSet(PluginMonitorWrapperLocator dataSourceMonitorLocator) { + public DataSourceMetricSet(PluginMonitorWrapperLocator dataSourceMonitorLocator, DatabaseInfoLocator databaseInfoLocator) { this.dataSourceMonitorLocator = dataSourceMonitorLocator; + this.databaseInfoLocator = databaseInfoLocator; } @Override @@ -43,7 +46,7 @@ public Map getMetrics() { final Map gauges = new HashMap(); for (DataSourceMonitorWrapper dataSourceMonitor : dataSourceMonitorList) { - gauges.put(MetricMonitorValues.DATASOURCE + "." + dataSourceMonitor.getId(), new DataSourceGauge(dataSourceMonitor)); + gauges.put(MetricMonitorValues.DATASOURCE + "." + dataSourceMonitor.getId(), new DataSourceGauge(dataSourceMonitor, databaseInfoLocator)); } return gauges; diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.java index 70d5f056fc38..4892ba678224 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultPluginContextLoadResult.java @@ -20,6 +20,7 @@ import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentEngine; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.profiler.context.ApplicationContext; import com.navercorp.pinpoint.profiler.context.module.BootstrapJarPaths; @@ -120,4 +121,18 @@ public List getApplicationTypeDetectorList() { return registeredDetectors; } + + @Override + public List getJdbcConnectionStringParserList() { + List result = new ArrayList(); + + List profilerPluginContextList = getProfilerPluginContextList(); + for (SetupResult context : profilerPluginContextList) { + List jdbcConnectionStringParserList = context.getJdbcConnectionStringParserList(); + result.addAll(jdbcConnectionStringParserList); + } + + return result; + } + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContext.java index e060e17ea7be..8c61d5f0a5f5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginContext.java @@ -16,17 +16,12 @@ package com.navercorp.pinpoint.profiler.plugin; -import java.io.InputStream; -import java.lang.instrument.ClassFileTransformer; -import java.util.ArrayList; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass; -import com.navercorp.pinpoint.bootstrap.instrument.InstrumentEngine; import com.navercorp.pinpoint.bootstrap.instrument.InstrumentContext; +import com.navercorp.pinpoint.bootstrap.instrument.InstrumentEngine; import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException; import com.navercorp.pinpoint.bootstrap.instrument.matcher.Matcher; import com.navercorp.pinpoint.bootstrap.instrument.matcher.Matchers; @@ -34,6 +29,7 @@ import com.navercorp.pinpoint.bootstrap.interceptor.scope.InterceptorScope; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import com.navercorp.pinpoint.profiler.context.ApplicationContext; import com.navercorp.pinpoint.profiler.context.scope.ConcurrentPool; import com.navercorp.pinpoint.profiler.context.scope.InterceptorScopeFactory; @@ -42,6 +38,11 @@ import com.navercorp.pinpoint.profiler.instrument.PluginClassInjector; import com.navercorp.pinpoint.profiler.util.JavaAssistUtils; +import java.io.InputStream; +import java.lang.instrument.ClassFileTransformer; +import java.util.ArrayList; +import java.util.List; + /** * @author jaehong.kim */ @@ -52,7 +53,9 @@ public class DefaultProfilerPluginContext implements ProfilerPluginSetupContext, private final List serverTypeDetectors = new ArrayList(); private final List classTransformers = new ArrayList(); - + + private final List jdbcConnectionStringParserList = new ArrayList(); + private final Pool interceptorScopePool = new ConcurrentPool(new InterceptorScopeFactory()); public DefaultProfilerPluginContext(ApplicationContext applicationContext, DynamicTransformTrigger dynamicTransformTrigger, ClassInjector classInjector) { @@ -207,4 +210,14 @@ public InterceptorScope getInterceptorScope(String name) { return interceptorScopePool.get(name); } + + @Override + public void addJdbcConnectionStringParser(JdbcConnectionStringParser jdbcConnectionStringParser) { + if (jdbcConnectionStringParser == null) { + return; + } + + this.jdbcConnectionStringParserList.add(jdbcConnectionStringParser); + } + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginSetupContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginSetupContext.java index b85476b2eb6a..59f2a1e7381e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginSetupContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/DefaultProfilerPluginSetupContext.java @@ -16,12 +16,13 @@ package com.navercorp.pinpoint.profiler.plugin; -import java.util.ArrayList; -import java.util.List; - import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; + +import java.util.ArrayList; +import java.util.List; /** @@ -29,10 +30,11 @@ */ public class DefaultProfilerPluginSetupContext implements ProfilerPluginSetupContext { - private final List serverTypeDetectors = new ArrayList(); - private final ProfilerConfig profilerConfig; + private final List serverTypeDetectors = new ArrayList(); + private final List jdbcConnectionStringParserList = new ArrayList(); + public DefaultProfilerPluginSetupContext(ProfilerConfig profilerConfig) { if (profilerConfig == null) { throw new NullPointerException("profilerConfig must not be null"); @@ -61,5 +63,17 @@ public List getApplicationTypeDetectors() { return serverTypeDetectors; } + @Override + public void addJdbcConnectionStringParser(JdbcConnectionStringParser jdbcConnectionStringParser) { + if (jdbcConnectionStringParser == null) { + return; + } + + this.jdbcConnectionStringParserList.add(jdbcConnectionStringParser); + } + + public List getJdbcConnectionStringParserList() { + return jdbcConnectionStringParserList; + } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/GuardProfilerPluginContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/GuardProfilerPluginContext.java index 90f57d8e12b3..4a770ff2085d 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/GuardProfilerPluginContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/GuardProfilerPluginContext.java @@ -19,6 +19,7 @@ import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; import com.navercorp.pinpoint.bootstrap.plugin.ProfilerPluginSetupContext; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; /** * @author emeroad @@ -49,6 +50,12 @@ public void addApplicationTypeDetector(ApplicationTypeDetector... detectors) { this.delegate.addApplicationTypeDetector(detectors); } + @Override + public void addJdbcConnectionStringParser(JdbcConnectionStringParser jdbcConnectionStringParser) { + checkOpen(); + this.delegate.addJdbcConnectionStringParser(jdbcConnectionStringParser); + } + private void checkOpen() { if (close) { throw new IllegalStateException("ProfilerPluginSetupContext already initialized"); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/PluginContextLoadResult.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/PluginContextLoadResult.java index d1246d583b29..ff186bb9e7d5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/PluginContextLoadResult.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/PluginContextLoadResult.java @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.profiler.plugin; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import java.lang.instrument.ClassFileTransformer; import java.util.List; @@ -29,4 +30,7 @@ public interface PluginContextLoadResult { List getClassFileTransformer(); List getApplicationTypeDetectorList(); + + List getJdbcConnectionStringParserList(); + } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/SetupResult.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/SetupResult.java index 0e769a8c686e..ad9050531477 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/SetupResult.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/SetupResult.java @@ -17,6 +17,7 @@ package com.navercorp.pinpoint.profiler.plugin; import com.navercorp.pinpoint.bootstrap.plugin.ApplicationTypeDetector; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; import java.lang.instrument.ClassFileTransformer; import java.util.List; @@ -39,6 +40,10 @@ public List getApplicationTypeDetectors() { return this.setupContext.getApplicationTypeDetectors(); } + public List getJdbcConnectionStringParserList() { + return this.setupContext.getJdbcConnectionStringParserList(); + } + public List getClassTransformerList() { return transformerRegistry.getClassTransformerList(); } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java index 7d44bb621c37..6195c1e53926 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockTraceContextFactory.java @@ -103,7 +103,8 @@ public MockTraceContextFactory(ProfilerConfig profilerConfig) { this.traceContext = new DefaultTraceContext(profilerConfig, agentInformation, traceFactoryBuilder, pluginMonitorContext, serverMetaDataHolder, - apiMetaDataCacheService, stringMetaDataCacheService, sqlMetaDataCacheService + apiMetaDataCacheService, stringMetaDataCacheService, sqlMetaDataCacheService, + DisabledJdbcUrlParserContext.INSTANCE ); } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoCacheTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoCacheTest.java new file mode 100644 index 000000000000..73bf5b844382 --- /dev/null +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DatabaseInfoCacheTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2017 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.profiler.context.monitor; + +import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParser; +import com.navercorp.pinpoint.common.trace.ServiceType; +import com.navercorp.pinpoint.profiler.context.DefaultJdbcConnectionStringParserContext; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +/** + * @author Taejin Koo + */ +public class DatabaseInfoCacheTest { + + private static final String MYSQL_NORMALIZED_URL = "jdbc:mysql://ip_address:3306/database_name"; + private static final String MYSQL_JDBC_URL = MYSQL_NORMALIZED_URL + "?useUnicode=yes&characterEncoding=UTF-8"; + + private final JdbcConnectionStringParser jdbcUrlParser = new MockJdbcUrlParser(); + + @Test + public void cacheTest1() throws Exception { + DefaultJdbcConnectionStringParserContext jdbcUrlParserContext = new DefaultJdbcConnectionStringParserContext(Arrays.asList(jdbcUrlParser)); + + DatabaseInfo databaseInfo = jdbcUrlParserContext.getDatabaseInfo(MYSQL_JDBC_URL); + Assert.assertNull(databaseInfo); + + DatabaseInfo parsingResult = jdbcUrlParserContext.parse(ServiceType.TEST, MYSQL_JDBC_URL); + Assert.assertTrue(parsingResult.isParsingComplete()); + + DatabaseInfo cache1 = jdbcUrlParserContext.getDatabaseInfo(MYSQL_JDBC_URL); + DatabaseInfo cache2 = jdbcUrlParserContext.getDatabaseInfo(MYSQL_JDBC_URL); + + Assert.assertTrue(parsingResult == cache1 && parsingResult == cache2); + } + + @Test + public void cacheTest2() throws Exception { + DefaultJdbcConnectionStringParserContext jdbcUrlParserContext = new DefaultJdbcConnectionStringParserContext(Arrays.asList(jdbcUrlParser)); + + DatabaseInfo parsingResult = jdbcUrlParserContext.parse(ServiceType.TEST, MYSQL_JDBC_URL); + Assert.assertTrue(parsingResult.isParsingComplete()); + + DatabaseInfo cache1 = jdbcUrlParserContext.getDatabaseInfo(ServiceType.TEST, MYSQL_JDBC_URL); + DatabaseInfo cache2 = jdbcUrlParserContext.getDatabaseInfo(ServiceType.UNKNOWN_DB, MYSQL_JDBC_URL); + + Assert.assertNotEquals(cache1, cache2); + } + + private static class MockJdbcUrlParser implements JdbcConnectionStringParser { + + @Override + public DatabaseInfo parse(String url) { + if (MYSQL_JDBC_URL.equals(url)) { + DatabaseInfo dbInfo = new DefaultDatabaseInfo(ServiceType.UNKNOWN_DB, ServiceType.UNKNOWN_DB_EXECUTE_QUERY, MYSQL_JDBC_URL, MYSQL_NORMALIZED_URL, Arrays.asList("ip_address:3306"), "database_name"); + return dbInfo; + } + return UnKnownDatabaseInfo.createUnknownDataBase(url); + } + + @Override + public ServiceType getServiceType() { + return ServiceType.TEST; + } + + } + +} diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DefaultPluginMonitorContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DefaultPluginMonitorContextTest.java index eb2a991b5659..fb309d9280b6 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DefaultPluginMonitorContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/monitor/DefaultPluginMonitorContextTest.java @@ -93,11 +93,6 @@ private static class MockDataSourceMonitor implements DataSourceMonitor { private boolean closed = false; - @Override - public String getName() { - return "name"; - } - @Override public String getUrl() { return "url"; diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/GarbageCollectorFactoryTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/GarbageCollectorFactoryTest.java index db86a2b5ce70..15c6adbd5568 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/GarbageCollectorFactoryTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/codahale/gc/GarbageCollectorFactoryTest.java @@ -22,12 +22,14 @@ import com.navercorp.pinpoint.profiler.context.DefaultTransactionCounter; import com.navercorp.pinpoint.profiler.context.TransactionCounter; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceRepository; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.context.monitor.DefaultPluginMonitorContext; import com.navercorp.pinpoint.profiler.context.monitor.PluginMonitorContext; import com.navercorp.pinpoint.profiler.monitor.codahale.AgentStatCollectorFactory; import com.navercorp.pinpoint.profiler.monitor.codahale.DefaultAgentStatCollectorFactory; import com.navercorp.pinpoint.thrift.dto.TJvmGc; import org.junit.Test; +import org.mockito.Mock; import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,6 +38,8 @@ public class GarbageCollectorFactoryTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Mock + private DatabaseInfoLocator databaseInfoLocator; private AgentStatCollectorFactory newAgentStatCollectorFactory(boolean detailedMetrics) { ProfilerConfig profilerConfig = Mockito.mock(DefaultProfilerConfig.class); @@ -48,7 +52,7 @@ private AgentStatCollectorFactory newAgentStatCollectorFactory(boolean detailedM TransactionCounter transactionCounter = new DefaultTransactionCounter(idGenerator); PluginMonitorContext pluginMonitorContext = new DefaultPluginMonitorContext(); - return new DefaultAgentStatCollectorFactory(profilerConfig, activeTraceRepository, transactionCounter, pluginMonitorContext); + return new DefaultAgentStatCollectorFactory(profilerConfig, activeTraceRepository, transactionCounter, pluginMonitorContext, databaseInfoLocator); } @@ -69,7 +73,6 @@ public void test() { @Test public void testDetailedMetrics() { - AgentStatCollectorFactory agentStatCollectorFactory = newAgentStatCollectorFactory(true); GarbageCollector collector = agentStatCollectorFactory.getGarbageCollector(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/datasource/DefaultDataSourceCollectorTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/datasource/DefaultDataSourceCollectorTest.java index afe366a4a007..696c1bafe477 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/datasource/DefaultDataSourceCollectorTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/monitor/datasource/DefaultDataSourceCollectorTest.java @@ -20,6 +20,7 @@ import com.navercorp.pinpoint.bootstrap.plugin.monitor.DataSourceMonitor; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.profiler.context.monitor.DataSourceMonitorList; +import com.navercorp.pinpoint.profiler.context.monitor.DatabaseInfoLocator; import com.navercorp.pinpoint.profiler.monitor.codahale.datasource.DefaultDataSourceCollector; import com.navercorp.pinpoint.profiler.monitor.codahale.datasource.metric.DataSourceGauge; import com.navercorp.pinpoint.profiler.monitor.codahale.datasource.metric.DataSourceMetricSet; @@ -27,6 +28,9 @@ import com.navercorp.pinpoint.thrift.dto.TDataSourceList; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Collection; @@ -39,8 +43,11 @@ /** * @author Taejin Koo */ +@RunWith(MockitoJUnitRunner.class) public class DefaultDataSourceCollectorTest { + @Mock + private DatabaseInfoLocator databaseInfoLocator; @Test public void collectTest() throws Exception { @@ -49,7 +56,9 @@ public void collectTest() throws Exception { DataSourceMonitorList dataSourceMonitorList = new DataSourceMonitorList(createMockObjectSize); MockDataSourceMonitor[] mockDataSourceMonitors = createMockDataSourceMonitor(dataSourceMonitorList, dataSourceMonitorList.getRemainingIdNumber()); - DataSourceMetricSet metricSet = new DataSourceMetricSet(dataSourceMonitorList); + System.out.println(databaseInfoLocator); + + DataSourceMetricSet metricSet = new DataSourceMetricSet(dataSourceMonitorList, databaseInfoLocator); DefaultDataSourceCollector dataSourceCollector = new DefaultDataSourceCollector(metricSet); TDataSourceList collect = dataSourceCollector.collect(); assertIdIsUnique(collect.getDataSourceList()); @@ -94,10 +103,9 @@ private void assertIdIsUnique(List dataSourceList) { private void assertContainsAndEquals(DataSourceMonitor dataSourceMonitor, List dataSourceList) { for (TDataSource dataSource : dataSourceList) { - String name = dataSourceMonitor.getName(); + String url = dataSourceMonitor.getUrl(); - if (name.equals(dataSource.getName())) { - Assert.assertEquals(dataSourceMonitor.getUrl(), dataSource.getUrl()); + if (url.equals(dataSource.getUrl())) { Assert.assertEquals(dataSourceMonitor.getActiveConnectionSize(), dataSource.getActiveConnectionSize()); Assert.assertEquals(dataSourceMonitor.getMaxConnectionSize(), dataSource.getMaxConnectionSize()); Assert.assertEquals(dataSourceMonitor.getServiceType().getCode(), dataSource.getServiceTypeCode()); @@ -128,11 +136,6 @@ public MockDataSourceMonitor(int index) { this.activeConnectionSize = RANDOM.nextInt(maxConnectionSize); } - @Override - public String getName() { - return "name" + id; - } - @Override public String getUrl() { return "url" + id; diff --git a/quickstart/web/src/main/resources/pinpoint-web.properties b/quickstart/web/src/main/resources/pinpoint-web.properties index 8496a4563ae0..8c2dceaf21ab 100644 --- a/quickstart/web/src/main/resources/pinpoint-web.properties +++ b/quickstart/web/src/main/resources/pinpoint-web.properties @@ -27,6 +27,9 @@ admin.password=admin config.sendUsage=true config.editUserInfo=true config.show.activeThread=true +config.show.activeThreadDump=false +config.show.inspector.dataSource=true +config.enable.activeThreadDump=false web.hbase.selectSpans.limit=500 web.hbase.selectAllSpans.limit=500 diff --git a/test/src/main/java/com/navercorp/pinpoint/test/mock/MockTraceContext.java b/test/src/main/java/com/navercorp/pinpoint/test/mock/MockTraceContext.java index 351a41fd5846..d3f9184d5bd8 100644 --- a/test/src/main/java/com/navercorp/pinpoint/test/mock/MockTraceContext.java +++ b/test/src/main/java/com/navercorp/pinpoint/test/mock/MockTraceContext.java @@ -25,6 +25,7 @@ import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.context.TraceId; +import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcConnectionStringParserContext; /** * @author emeroad @@ -159,4 +160,11 @@ public Trace continueTraceObject(Trace trace) { public Trace removeTraceObject() { return null; } + + @Override + public JdbcConnectionStringParserContext getJdbcUrlParserContext() { +// return new + return null; + } + } \ No newline at end of file diff --git a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TDataSource.java b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TDataSource.java index 50e6c7ec866f..a38b1271d875 100644 --- a/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TDataSource.java +++ b/thrift/src/main/java/com/navercorp/pinpoint/thrift/dto/TDataSource.java @@ -24,13 +24,13 @@ import java.util.Map; @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"}) -@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-1-24") +@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2017-2-22") public class TDataSource implements org.apache.thrift.TBase, java.io.Serializable, Cloneable, Comparable { private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TDataSource"); private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)1); private static final org.apache.thrift.protocol.TField SERVICE_TYPE_CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("serviceTypeCode", org.apache.thrift.protocol.TType.I16, (short)2); - private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)3); + private static final org.apache.thrift.protocol.TField DATABASE_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("databaseName", org.apache.thrift.protocol.TType.STRING, (short)3); private static final org.apache.thrift.protocol.TField URL_FIELD_DESC = new org.apache.thrift.protocol.TField("url", org.apache.thrift.protocol.TType.STRING, (short)4); private static final org.apache.thrift.protocol.TField ACTIVE_CONNECTION_SIZE_FIELD_DESC = new org.apache.thrift.protocol.TField("activeConnectionSize", org.apache.thrift.protocol.TType.I32, (short)5); private static final org.apache.thrift.protocol.TField MAX_CONNECTION_SIZE_FIELD_DESC = new org.apache.thrift.protocol.TField("maxConnectionSize", org.apache.thrift.protocol.TType.I32, (short)6); @@ -43,7 +43,7 @@ public class TDataSource implements org.apache.thrift.TBase metaDataMap; static { Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); @@ -135,7 +135,7 @@ public String getFieldName() { new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))); tmpMap.put(_Fields.SERVICE_TYPE_CODE, new org.apache.thrift.meta_data.FieldMetaData("serviceTypeCode", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16))); - tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, + tmpMap.put(_Fields.DATABASE_NAME, new org.apache.thrift.meta_data.FieldMetaData("databaseName", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); tmpMap.put(_Fields.URL, new org.apache.thrift.meta_data.FieldMetaData("url", org.apache.thrift.TFieldRequirementType.OPTIONAL, new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); @@ -167,8 +167,8 @@ public TDataSource(TDataSource other) { __isset_bitfield = other.__isset_bitfield; this.id = other.id; this.serviceTypeCode = other.serviceTypeCode; - if (other.isSetName()) { - this.name = other.name; + if (other.isSetDatabaseName()) { + this.databaseName = other.databaseName; } if (other.isSetUrl()) { this.url = other.url; @@ -187,7 +187,7 @@ public void clear() { this.id = 0; setServiceTypeCodeIsSet(false); this.serviceTypeCode = 0; - this.name = null; + this.databaseName = null; this.url = null; this.activeConnectionSize = 0; @@ -239,26 +239,26 @@ public void setServiceTypeCodeIsSet(boolean value) { __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __SERVICETYPECODE_ISSET_ID, value); } - public String getName() { - return this.name; + public String getDatabaseName() { + return this.databaseName; } - public void setName(String name) { - this.name = name; + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; } - public void unsetName() { - this.name = null; + public void unsetDatabaseName() { + this.databaseName = null; } - /** Returns true if field name is set (has been assigned a value) and false otherwise */ - public boolean isSetName() { - return this.name != null; + /** Returns true if field databaseName is set (has been assigned a value) and false otherwise */ + public boolean isSetDatabaseName() { + return this.databaseName != null; } - public void setNameIsSet(boolean value) { + public void setDatabaseNameIsSet(boolean value) { if (!value) { - this.name = null; + this.databaseName = null; } } @@ -347,11 +347,11 @@ public void setFieldValue(_Fields field, Object value) { } break; - case NAME: + case DATABASE_NAME: if (value == null) { - unsetName(); + unsetDatabaseName(); } else { - setName((String)value); + setDatabaseName((String)value); } break; @@ -390,8 +390,8 @@ public Object getFieldValue(_Fields field) { case SERVICE_TYPE_CODE: return Short.valueOf(getServiceTypeCode()); - case NAME: - return getName(); + case DATABASE_NAME: + return getDatabaseName(); case URL: return getUrl(); @@ -417,8 +417,8 @@ public boolean isSet(_Fields field) { return isSetId(); case SERVICE_TYPE_CODE: return isSetServiceTypeCode(); - case NAME: - return isSetName(); + case DATABASE_NAME: + return isSetDatabaseName(); case URL: return isSetUrl(); case ACTIVE_CONNECTION_SIZE: @@ -460,12 +460,12 @@ public boolean equals(TDataSource that) { return false; } - boolean this_present_name = true && this.isSetName(); - boolean that_present_name = true && that.isSetName(); - if (this_present_name || that_present_name) { - if (!(this_present_name && that_present_name)) + boolean this_present_databaseName = true && this.isSetDatabaseName(); + boolean that_present_databaseName = true && that.isSetDatabaseName(); + if (this_present_databaseName || that_present_databaseName) { + if (!(this_present_databaseName && that_present_databaseName)) return false; - if (!this.name.equals(that.name)) + if (!this.databaseName.equals(that.databaseName)) return false; } @@ -513,10 +513,10 @@ public int hashCode() { if (present_serviceTypeCode) list.add(serviceTypeCode); - boolean present_name = true && (isSetName()); - list.add(present_name); - if (present_name) - list.add(name); + boolean present_databaseName = true && (isSetDatabaseName()); + list.add(present_databaseName); + if (present_databaseName) + list.add(databaseName); boolean present_url = true && (isSetUrl()); list.add(present_url); @@ -564,12 +564,12 @@ public int compareTo(TDataSource other) { return lastComparison; } } - lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName()); + lastComparison = Boolean.valueOf(isSetDatabaseName()).compareTo(other.isSetDatabaseName()); if (lastComparison != 0) { return lastComparison; } - if (isSetName()) { - lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name); + if (isSetDatabaseName()) { + lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.databaseName, other.databaseName); if (lastComparison != 0) { return lastComparison; } @@ -633,13 +633,13 @@ public String toString() { sb.append(this.serviceTypeCode); first = false; } - if (isSetName()) { + if (isSetDatabaseName()) { if (!first) sb.append(", "); - sb.append("name:"); - if (this.name == null) { + sb.append("databaseName:"); + if (this.databaseName == null) { sb.append("null"); } else { - sb.append(this.name); + sb.append(this.databaseName); } first = false; } @@ -726,10 +726,10 @@ public void read(org.apache.thrift.protocol.TProtocol iprot, TDataSource struct) org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } break; - case 3: // NAME + case 3: // DATABASE_NAME if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { - struct.name = iprot.readString(); - struct.setNameIsSet(true); + struct.databaseName = iprot.readString(); + struct.setDatabaseNameIsSet(true); } else { org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); } @@ -779,10 +779,10 @@ public void write(org.apache.thrift.protocol.TProtocol oprot, TDataSource struct oprot.writeI16(struct.serviceTypeCode); oprot.writeFieldEnd(); } - if (struct.name != null) { - if (struct.isSetName()) { - oprot.writeFieldBegin(NAME_FIELD_DESC); - oprot.writeString(struct.name); + if (struct.databaseName != null) { + if (struct.isSetDatabaseName()) { + oprot.writeFieldBegin(DATABASE_NAME_FIELD_DESC); + oprot.writeString(struct.databaseName); oprot.writeFieldEnd(); } } @@ -827,7 +827,7 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TDataSource struct) if (struct.isSetServiceTypeCode()) { optionals.set(1); } - if (struct.isSetName()) { + if (struct.isSetDatabaseName()) { optionals.set(2); } if (struct.isSetUrl()) { @@ -846,8 +846,8 @@ public void write(org.apache.thrift.protocol.TProtocol prot, TDataSource struct) if (struct.isSetServiceTypeCode()) { oprot.writeI16(struct.serviceTypeCode); } - if (struct.isSetName()) { - oprot.writeString(struct.name); + if (struct.isSetDatabaseName()) { + oprot.writeString(struct.databaseName); } if (struct.isSetUrl()) { oprot.writeString(struct.url); @@ -873,8 +873,8 @@ public void read(org.apache.thrift.protocol.TProtocol prot, TDataSource struct) struct.setServiceTypeCodeIsSet(true); } if (incoming.get(2)) { - struct.name = iprot.readString(); - struct.setNameIsSet(true); + struct.databaseName = iprot.readString(); + struct.setDatabaseNameIsSet(true); } if (incoming.get(3)) { struct.url = iprot.readString(); diff --git a/thrift/src/main/thrift/Pinpoint.thrift b/thrift/src/main/thrift/Pinpoint.thrift index 54d76768f6c4..b93a95d47631 100644 --- a/thrift/src/main/thrift/Pinpoint.thrift +++ b/thrift/src/main/thrift/Pinpoint.thrift @@ -113,7 +113,7 @@ struct TAgentStatBatch { struct TDataSource { 1: i32 id 2: optional i16 serviceTypeCode - 3: optional string name + 3: optional string databaseName 4: optional string url 5: optional i32 activeConnectionSize = 0 6: optional i32 maxConnectionSize diff --git a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/DataSourceSampler.java b/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/DataSourceSampler.java index 051668c5637c..f98c8e6af814 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/DataSourceSampler.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/mapper/stat/sampling/sampler/DataSourceSampler.java @@ -47,7 +47,7 @@ public SampledDataSource sampleDataPoints(int timeWindowIndex, long timestamp, L DataSourceBo defaultDataSourceBo = dataSourceBoList.get(0); int id = defaultDataSourceBo.getId(); short serviceTypeCode = defaultDataSourceBo.getServiceTypeCode(); - String name = defaultDataSourceBo.getName(); + String databaseName = defaultDataSourceBo.getDatabaseName(); String jdbcUrl = defaultDataSourceBo.getJdbcUrl(); for (DataSourceBo dataSourceBo : dataSourceBoList) { int activeConnectionSize = dataSourceBo.getActiveConnectionSize(); @@ -66,8 +66,8 @@ public SampledDataSource sampleDataPoints(int timeWindowIndex, long timestamp, L throw new IllegalArgumentException("serviceTypeCode must be same"); } - if (name == null && dataSourceBo.getName() != null) { - name = dataSourceBo.getName(); + if (databaseName == null && dataSourceBo.getDatabaseName() != null) { + databaseName = dataSourceBo.getDatabaseName(); } if (jdbcUrl == null && dataSourceBo.getJdbcUrl() != null) { @@ -78,7 +78,7 @@ public SampledDataSource sampleDataPoints(int timeWindowIndex, long timestamp, L SampledDataSource sampledDataSource = new SampledDataSource(); sampledDataSource.setId(id); sampledDataSource.setServiceTypeCode(serviceTypeCode); - sampledDataSource.setName(name); + sampledDataSource.setDatabaseName(databaseName); sampledDataSource.setJdbcUrl(jdbcUrl); sampledDataSource.setActiveConnectionSize(createPoint(timestamp, activeConnectionSizes)); sampledDataSource.setMaxConnectionSize(createPoint(timestamp, maxConnectionSizes)); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializer.java b/web/src/main/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializer.java index 68567074bb58..9080b75d4c4a 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializer.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializer.java @@ -35,7 +35,7 @@ public void serialize(DataSourceChartGroup dataSourceChartGroup, JsonGenerator j jgen.writeNumberField("id", dataSourceChartGroup.getId()); jgen.writeStringField("jdbcUrl", dataSourceChartGroup.getJdbcUrl()); - jgen.writeStringField("poolName", dataSourceChartGroup.getPoolName()); + jgen.writeStringField("databaseName", dataSourceChartGroup.getDatabaseName()); jgen.writeStringField("serviceType", dataSourceChartGroup.getServiceTypeName()); jgen.writeObjectField("charts", dataSourceChartGroup.getCharts()); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledDataSource.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledDataSource.java index 12401b0441c6..eec75b774e53 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledDataSource.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/SampledDataSource.java @@ -25,7 +25,7 @@ public class SampledDataSource implements SampledAgentStatDataPoint { private int id; private short serviceTypeCode; - private String name; + private String databaseName; private String jdbcUrl; private Point activeConnectionSize; private Point maxConnectionSize; @@ -46,12 +46,12 @@ public void setServiceTypeCode(short serviceTypeCode) { this.serviceTypeCode = serviceTypeCode; } - public String getName() { - return name; + public String getDatabaseName() { + return databaseName; } - public void setName(String name) { - this.name = name; + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; } public String getJdbcUrl() { @@ -87,7 +87,7 @@ public boolean equals(Object o) { if (id != that.id) return false; if (serviceTypeCode != that.serviceTypeCode) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (databaseName != null ? !databaseName.equals(that.databaseName) : that.databaseName != null) return false; if (jdbcUrl != null ? !jdbcUrl.equals(that.jdbcUrl) : that.jdbcUrl != null) return false; if (activeConnectionSize != null ? !activeConnectionSize.equals(that.activeConnectionSize) : that.activeConnectionSize != null) return false; return maxConnectionSize != null ? maxConnectionSize.equals(that.maxConnectionSize) : that.maxConnectionSize == null; @@ -98,7 +98,7 @@ public boolean equals(Object o) { public int hashCode() { int result = id; result = 31 * result + (int) serviceTypeCode; - result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (databaseName != null ? databaseName.hashCode() : 0); result = 31 * result + (jdbcUrl != null ? jdbcUrl.hashCode() : 0); result = 31 * result + (activeConnectionSize != null ? activeConnectionSize.hashCode() : 0); result = 31 * result + (maxConnectionSize != null ? maxConnectionSize.hashCode() : 0); @@ -110,7 +110,7 @@ public String toString() { final StringBuilder sb = new StringBuilder("SampledDataSource{"); sb.append("id=").append(id); sb.append(", serviceTypeCode=").append(serviceTypeCode); - sb.append(", name='").append(name).append('\''); + sb.append(", databaseName='").append(databaseName).append('\''); sb.append(", jdbcUrl='").append(jdbcUrl).append('\''); sb.append(", activeConnectionSize=").append(activeConnectionSize); sb.append(", maxConnectionSize=").append(maxConnectionSize); diff --git a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroup.java b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroup.java index f134a9545387..53b8b2d27e70 100644 --- a/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroup.java +++ b/web/src/main/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroup.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.navercorp.pinpoint.common.service.ServiceTypeRegistryService; -import com.navercorp.pinpoint.rpc.util.ListUtils; +import com.navercorp.pinpoint.common.util.CollectionUtils; import com.navercorp.pinpoint.web.util.TimeWindow; import com.navercorp.pinpoint.web.view.DataSourceChartGroupSerializer; import com.navercorp.pinpoint.web.vo.chart.Chart; @@ -49,7 +49,7 @@ public enum DataSourceChartType implements ChartType { private final int id; private final String serviceTypeName; - private final String poolName; + private final String databaseName; private final String jdbcUrl; public DataSourceChartGroup(TimeWindow timeWindow, List sampledDataSourceList, ServiceTypeRegistryService serviceTypeRegistryService) { @@ -65,20 +65,31 @@ public DataSourceChartGroup(TimeWindow timeWindow, List sampl this.dataSourceCharts.put(DataSourceChartType.ACTIVE_CONNECTION_SIZE, new TimeSeriesChartBuilder<>(timeWindow, UNCOLLECTED_VALUE).build(activeConnectionSizes)); this.dataSourceCharts.put(DataSourceChartType.MAX_CONNECTION_SIZE, new TimeSeriesChartBuilder<>(timeWindow, UNCOLLECTED_VALUE).build(maxConnectionSizes)); - SampledDataSource defaultDataSource = ListUtils.getFirst(sampledDataSourceList); - if (defaultDataSource != null) { - this.id = defaultDataSource.getId(); - this.serviceTypeName = serviceTypeRegistryService.findServiceType(defaultDataSource.getServiceTypeCode()).getName(); - this.poolName = defaultDataSource.getName(); - this.jdbcUrl = defaultDataSource.getJdbcUrl(); - } else { + if (CollectionUtils.nullSafeSize(sampledDataSourceList) == 0) { this.id = UNCOLLECTED_VALUE; this.serviceTypeName = UNCOLLECTED_STRING_VALUE; - this.poolName = UNCOLLECTED_STRING_VALUE; + this.databaseName = UNCOLLECTED_STRING_VALUE; this.jdbcUrl = UNCOLLECTED_STRING_VALUE; + } else { + SampledDataSource defaultDataSource = sampledDataSourceList.get(0); + + this.id = defaultDataSource.getId(); + this.serviceTypeName = serviceTypeRegistryService.findServiceType(defaultDataSource.getServiceTypeCode()).getName(); + this.databaseName = extractDatabaseName(sampledDataSourceList); + this.jdbcUrl = defaultDataSource.getJdbcUrl(); } } + private String extractDatabaseName(List sampledDataSourceList) { + for (SampledDataSource sampledDataSource : sampledDataSourceList) { + if (sampledDataSource != null && sampledDataSource.getDatabaseName() != null) { + return sampledDataSource.getDatabaseName(); + } + } + + return null; + } + @Override public Map getCharts() { return dataSourceCharts; @@ -92,8 +103,8 @@ public String getServiceTypeName() { return serviceTypeName; } - public String getPoolName() { - return poolName; + public String getDatabaseName() { + return databaseName; } public String getJdbcUrl() { diff --git a/web/src/main/resources/pinpoint-web.properties b/web/src/main/resources/pinpoint-web.properties index 977b2ca1dbb9..4271f5d759ef 100644 --- a/web/src/main/resources/pinpoint-web.properties +++ b/web/src/main/resources/pinpoint-web.properties @@ -34,7 +34,7 @@ config.editUserInfo=true config.openSource=true config.show.activeThread=true config.show.activeThreadDump=false -config.show.inspector.dataSource=false +config.show.inspector.dataSource=true config.enable.activeThreadDump=false web.hbase.selectSpans.limit=500 diff --git a/web/src/test/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializerTest.java b/web/src/test/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializerTest.java index f52de6460f24..9e5061e82f44 100644 --- a/web/src/test/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializerTest.java +++ b/web/src/test/java/com/navercorp/pinpoint/web/view/DataSourceChartGroupSerializerTest.java @@ -75,7 +75,7 @@ public void serializeTest() throws Exception { Assert.assertTrue(map.containsKey("id")); Assert.assertTrue(map.containsKey("jdbcUrl")); - Assert.assertTrue(map.containsKey("poolName")); + Assert.assertTrue(map.containsKey("databaseName")); Assert.assertTrue(map.containsKey("serviceType")); Assert.assertTrue(map.containsKey("charts")); } diff --git a/web/src/test/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroupTest.java b/web/src/test/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroupTest.java index 682c9b0f4698..f223e3533b44 100644 --- a/web/src/test/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroupTest.java +++ b/web/src/test/java/com/navercorp/pinpoint/web/vo/stat/chart/DataSourceChartGroupTest.java @@ -82,7 +82,7 @@ public void basicFunctionTest2() throws Exception { Assert.assertEquals(-1, dataSourceChartGroup.getId()); Assert.assertEquals(null, dataSourceChartGroup.getJdbcUrl()); - Assert.assertEquals(null, dataSourceChartGroup.getPoolName()); + Assert.assertEquals(null, dataSourceChartGroup.getDatabaseName()); Assert.assertEquals(null, dataSourceChartGroup.getServiceTypeName()); }