1
18 package net.bull.javamelody;
19
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Method;
22
23 import org.springframework.beans.factory.config.BeanPostProcessor;
24 import org.springframework.core.PriorityOrdered;
25 import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
26
27 import net.bull.javamelody.internal.common.LOG;
28 import net.bull.javamelody.internal.common.Parameters;
29 import net.bull.javamelody.internal.model.Counter;
30
31
35 public class SpringElasticsearchOperationsBeanPostProcessor
36 implements BeanPostProcessor, PriorityOrdered {
37 private static final boolean ELASTICSEARCH_OPERATIONS_AVAILABLE = isElasticsearchOperationsAvailable();
38 private static final Counter SERVICES_COUNTER = MonitoringProxy.getServicesCounter();
39 private static final boolean COUNTER_HIDDEN = Parameters
40 .isCounterHidden(SERVICES_COUNTER.getName());
41 private static final boolean DISABLED = Parameter.DISABLED.getValueAsBoolean();
42
43
44
45 private int order = LOWEST_PRECEDENCE;
46
47
48 @Override
49 public int getOrder() {
50 return order;
51 }
52
53
57 public void setOrder(int order) {
58 this.order = order;
59 }
60
61
62 @Override
63 public Object postProcessBeforeInitialization(Object bean, String beanName) {
64 return bean;
65 }
66
67
68 @Override
69 public Object postProcessAfterInitialization(Object bean, String beanName) {
70 if (ELASTICSEARCH_OPERATIONS_AVAILABLE && bean instanceof ElasticsearchOperations) {
71 final ElasticsearchOperations elasticsearchOperations = (ElasticsearchOperations) bean;
72 if (DISABLED) {
73 return elasticsearchOperations;
74 }
75 SERVICES_COUNTER.setDisplayed(!COUNTER_HIDDEN);
76 SERVICES_COUNTER.setUsed(true);
77
78 final InvocationHandler invocationHandler = new InvocationHandler() {
79
80 @Override
81 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
82 final StringBuilder requestName = new StringBuilder();
83 requestName.append("elasticsearch.").append(method.getName()).append('(');
84 if (args != null) {
85 boolean first = true;
86 for (final Object arg : args) {
87 if (first) {
88 first = false;
89 } else {
90 requestName.append(", ");
91 }
92 if (arg == null) {
93 requestName.append("null");
94 } else if (arg instanceof Class) {
95 requestName.append(((Class<?>) arg).getSimpleName());
96 } else {
97 requestName.append(arg.getClass().getSimpleName());
98 }
99 }
100 }
101 requestName.append(')');
102 return doInvoke(elasticsearchOperations, method, args, requestName.toString());
103 }
104 };
105 final ElasticsearchOperations ops = JdbcWrapper.createProxy(elasticsearchOperations,
106 invocationHandler);
107 LOG.debug("elasticsearch operations monitoring initialized");
108 return ops;
109 }
110
111 return bean;
112 }
113
114 static Object doInvoke(final Object object, final Method method, final Object[] args,
115 final String requestName) throws Throwable {
116 boolean systemError = false;
117 try {
118 SERVICES_COUNTER.bindContextIncludingCpu(requestName);
119 return method.invoke(object, args);
120 } catch (final Error e) {
121
122
123 systemError = true;
124 throw e;
125 } finally {
126
127 SERVICES_COUNTER.addRequestForCurrentContext(systemError);
128 }
129 }
130
131 private static boolean isElasticsearchOperationsAvailable() {
132 try {
133 Class.forName("org.springframework.data.elasticsearch.core.ElasticsearchOperations");
134 return true;
135 } catch (final ClassNotFoundException e) {
136 return false;
137 }
138 }
139 }
140