/* * 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.recorder; import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor; import com.navercorp.pinpoint.common.trace.AnnotationKey; import com.navercorp.pinpoint.common.util.AnnotationKeyUtils; import com.navercorp.pinpoint.common.util.StringUtils; import com.navercorp.pinpoint.profiler.context.Annotation; import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataService; import com.navercorp.pinpoint.profiler.metadata.StringMetaDataService; /** * * @author jaehong.kim * */ public abstract class AbstractRecorder { protected final StringMetaDataService stringMetaDataService; protected final SqlMetaDataService sqlMetaDataService; public AbstractRecorder(final StringMetaDataService stringMetaDataService, SqlMetaDataService sqlMetaDataService) { if (stringMetaDataService == null) { throw new NullPointerException("stringMetaDataService must not be null"); } if (sqlMetaDataService == null) { throw new NullPointerException("sqlMetaDataService must not be null"); } this.stringMetaDataService = stringMetaDataService; this.sqlMetaDataService = sqlMetaDataService; } public void recordException(Throwable throwable) { recordException(true, throwable); } public void recordException(boolean markError, Throwable throwable) { if (throwable == null) { return; } final String drop = StringUtils.abbreviate(throwable.getMessage(), 256); // An exception that is an instance of a proxy class could make something wrong because the class name will vary. final int exceptionId = stringMetaDataService.cacheString(throwable.getClass().getName()); setExceptionInfo(markError, exceptionId, drop); } abstract void setExceptionInfo(int exceptionClassId, String exceptionMessage); abstract void setExceptionInfo(boolean markError, int exceptionClassId, String exceptionMessage); public void recordApi(MethodDescriptor methodDescriptor) { if (methodDescriptor == null) { return; } if (methodDescriptor.getApiId() == 0) { recordAttribute(AnnotationKey.API, methodDescriptor.getFullName()); } else { setApiId0(methodDescriptor.getApiId()); } } public void recordApi(MethodDescriptor methodDescriptor, Object[] args) { recordApi(methodDescriptor); recordArgs(args); } public void recordApi(MethodDescriptor methodDescriptor, Object args, int index) { recordApi(methodDescriptor); recordSingleArg(args, index); } public void recordApi(MethodDescriptor methodDescriptor, Object[] args, int start, int end) { recordApi(methodDescriptor); recordArgs(args, start, end); } public void recordApiCachedString(MethodDescriptor methodDescriptor, String args, int index) { recordApi(methodDescriptor); recordSingleCachedString(args, index); } abstract void setApiId0(final int apiId); private void recordArgs(Object[] args, int start, int end) { if (args != null) { int max = Math.min(Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE), end); for (int i = start; i < max; i++) { recordAttribute(AnnotationKeyUtils.getArgs(i), args[i]); } // TODO How to handle if args length is greater than MAX_ARGS_SIZE? } } private void recordSingleArg(Object args, int index) { if (args != null) { recordAttribute(AnnotationKeyUtils.getArgs(index), args); } } private void recordSingleCachedString(String args, int index) { if (args != null) { int cacheId = stringMetaDataService.cacheString(args); recordAttribute(AnnotationKeyUtils.getCachedArgs(index), cacheId); } } private void recordArgs(Object[] args) { if (args != null) { int max = Math.min(args.length, AnnotationKey.MAX_ARGS_SIZE); for (int i = 0; i < max; i++) { recordAttribute(AnnotationKeyUtils.getArgs(i), args[i]); } // TODO How to handle if args length is greater than MAX_ARGS_SIZE? } } public void recordAttribute(AnnotationKey key, String value) { addAnnotation(new Annotation(key.getCode(), value)); } public void recordAttribute(AnnotationKey key, int value) { addAnnotation(new Annotation(key.getCode(), value)); } public void recordAttribute(AnnotationKey key, Object value) { addAnnotation(new Annotation(key.getCode(), value)); } abstract void addAnnotation(Annotation annotation); }