/plugins/mongodb/src/main/java/com/navercorp/pinpoint/plugin/mongo/interceptor/MongoDriverConnectInterceptor3_0.java

https://github.com/naver/pinpoint · Java · 155 lines · 103 code · 33 blank · 19 comment · 13 complexity · 35eb566fc8889411d4c27f1405142c02 MD5 · raw file

  1. /*
  2. * Copyright 2018 NAVER Corp.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.navercorp.pinpoint.plugin.mongo.interceptor;
  17. import com.mongodb.MongoClientOptions;
  18. import com.mongodb.ServerAddress;
  19. import com.mongodb.connection.Cluster;
  20. import com.mongodb.connection.ClusterDescription;
  21. import com.mongodb.connection.ServerDescription;
  22. import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo;
  23. import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
  24. import com.navercorp.pinpoint.bootstrap.logging.PLogger;
  25. import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
  26. import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DatabaseInfoAccessor;
  27. import com.navercorp.pinpoint.bootstrap.plugin.jdbc.MongoDatabaseInfo;
  28. import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo;
  29. import com.navercorp.pinpoint.bootstrap.util.InterceptorUtils;
  30. import com.navercorp.pinpoint.common.plugin.util.HostAndPort;
  31. import com.navercorp.pinpoint.plugin.mongo.MongoConstants;
  32. import com.navercorp.pinpoint.plugin.mongo.MongoUtil;
  33. import java.util.ArrayList;
  34. import java.util.Collection;
  35. import java.util.Collections;
  36. import java.util.List;
  37. /**
  38. * @author Roy Kim
  39. */
  40. public class MongoDriverConnectInterceptor3_0 implements AroundInterceptor {
  41. private final PLogger logger = PLoggerFactory.getLogger(this.getClass());
  42. private final boolean isDebug = logger.isDebugEnabled();
  43. public MongoDriverConnectInterceptor3_0() {
  44. }
  45. @Override
  46. public void before(Object target, Object[] args) {
  47. if (isDebug) {
  48. logBeforeInterceptor(target, args);
  49. }
  50. }
  51. @Override
  52. public void after(Object target, Object[] args, Object result, Throwable throwable) {
  53. if (isDebug) {
  54. logAfterInterceptor(target, args, result, throwable);
  55. }
  56. final boolean success = InterceptorUtils.isSuccess(throwable);
  57. // Must not check if current transaction is trace target or not. Connection can be made by other thread.
  58. if (success) {
  59. if (args == null) {
  60. return;
  61. }
  62. final List<String> hostList = getHostList(args[0]);
  63. String readPreference = getReadPreference(args[1]);
  64. String writeConcern = getWriteConcern(args[1]);
  65. DatabaseInfo databaseInfo = createDatabaseInfo(hostList, readPreference, writeConcern);
  66. if (databaseInfo == null) {
  67. databaseInfo = UnKnownDatabaseInfo.MONGO_INSTANCE;
  68. }
  69. if (target instanceof DatabaseInfoAccessor) {
  70. ((DatabaseInfoAccessor) target)._$PINPOINT$_setDatabaseInfo(databaseInfo);
  71. }
  72. }
  73. }
  74. private void logBeforeInterceptor(Object target, Object[] args) {
  75. logger.beforeInterceptor(target, args);
  76. }
  77. private void logAfterInterceptor(Object target, Object[] args, Object result, Throwable throwable) {
  78. logger.afterInterceptor(target, args, result, throwable);
  79. }
  80. private DatabaseInfo createDatabaseInfo(List<String> hostList, String readPreference, String writeConcern) {
  81. DatabaseInfo databaseInfo = new MongoDatabaseInfo(MongoConstants.MONGODB, MongoConstants.MONGO_EXECUTE_QUERY,
  82. null, null, hostList, null, null, readPreference, writeConcern);
  83. if (isDebug) {
  84. logger.debug("parse DatabaseInfo:{}", databaseInfo);
  85. }
  86. return databaseInfo;
  87. }
  88. private List<String> getHostList(Object arg) {
  89. if (!(arg instanceof Cluster)) {
  90. return Collections.emptyList();
  91. }
  92. final Cluster cluster = (Cluster) arg;
  93. final List<String> hostList = new ArrayList<String>();
  94. Collection<ServerDescription> serverDescriptions;// = cluster.getDescription().getAll();//.getServerDescriptions();
  95. try {
  96. ClusterDescription.class.getDeclaredMethod("getServerDescriptions");
  97. serverDescriptions = cluster.getDescription().getServerDescriptions();
  98. } catch (NoSuchMethodException e) {
  99. serverDescriptions = cluster.getDescription().getAll();
  100. }
  101. for (ServerDescription serverDescription : serverDescriptions) {
  102. ServerAddress serverAddress = serverDescription.getAddress();
  103. final String hostAddress = HostAndPort.toHostAndPortString(serverAddress.getHost(), serverAddress.getPort());
  104. hostList.add(hostAddress);
  105. }
  106. return hostList;
  107. }
  108. private String getReadPreference(Object arg) {
  109. if (!(arg instanceof MongoClientOptions)) {
  110. return null;
  111. }
  112. final MongoClientOptions mongoClientOptions = (MongoClientOptions) arg;
  113. return mongoClientOptions.getReadPreference().getName();
  114. }
  115. private String getWriteConcern(Object arg) {
  116. if (!(arg instanceof MongoClientOptions)) {
  117. return null;
  118. }
  119. final MongoClientOptions mongoClientOptions = (MongoClientOptions) arg;
  120. return MongoUtil.getWriteConcern0(mongoClientOptions.getWriteConcern());
  121. }
  122. }