/* * Copyright 2016 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.receiver.service; import com.navercorp.pinpoint.common.util.JvmUtils; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceInfo; import com.navercorp.pinpoint.profiler.context.active.ActiveTraceRepository; import com.navercorp.pinpoint.profiler.receiver.ProfilerRequestCommandService; import com.navercorp.pinpoint.profiler.util.ActiveThreadDumpUtils; import com.navercorp.pinpoint.profiler.util.ThreadDumpUtils; import com.navercorp.pinpoint.thrift.dto.command.TActiveThreadLightDump; import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadLightDump; import com.navercorp.pinpoint.thrift.dto.command.TCmdActiveThreadLightDumpRes; import com.navercorp.pinpoint.thrift.dto.command.TThreadLightDump; import org.apache.thrift.TBase; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @author Taejin Koo */ public class ActiveThreadLightDumpService implements ProfilerRequestCommandService { private final ActiveTraceRepository activeTraceRepository; public ActiveThreadLightDumpService(ActiveTraceRepository activeTraceRepository) { this.activeTraceRepository = activeTraceRepository; } @Override public TBase<?, ?> requestCommandService(TBase tBase) { TCmdActiveThreadLightDump request = (TCmdActiveThreadLightDump) tBase; List<TActiveThreadLightDump> activeThreadDumpList = getActiveThreadDumpList(request); TCmdActiveThreadLightDumpRes response = new TCmdActiveThreadLightDumpRes(); response.setType("JAVA"); response.setSubType(JvmUtils.getType().name()); response.setVersion(JvmUtils.getVersion().name()); response.setThreadDumps(activeThreadDumpList); return response; } private List<TActiveThreadLightDump> getActiveThreadDumpList(TCmdActiveThreadLightDump request) { List<ActiveTraceInfo> activeTraceInfoList = activeTraceRepository.collect(); int limit = request.getLimit(); if (limit > 0) { Collections.sort(activeTraceInfoList, ActiveThreadDumpUtils.getActiveTraceInfoComparator()); } else { limit = Integer.MAX_VALUE; } return getTActiveThreadDumpList(request, limit, activeTraceInfoList); } private List<TActiveThreadLightDump> getTActiveThreadDumpList(TCmdActiveThreadLightDump request, int limit, List<ActiveTraceInfo> activeTraceInfoList) { int targetThreadNameListSize = request.getThreadNameListSize(); int localTraceIdListSize = request.getLocalTraceIdListSize(); boolean filterEnable = (targetThreadNameListSize + localTraceIdListSize) > 0; List<TActiveThreadLightDump> activeThreadDumpList = new ArrayList<TActiveThreadLightDump>(Math.min(limit, activeTraceInfoList.size())); if (filterEnable) { for (ActiveTraceInfo activeTraceInfo : activeTraceInfoList) { if (!ActiveThreadDumpUtils.isTraceThread(activeTraceInfo, request.getThreadNameList(), request.getLocalTraceIdList())) { continue; } TActiveThreadLightDump activeThreadDump = createActiveLightThreadDump(activeTraceInfo); if (activeThreadDump != null) { if (limit > activeThreadDumpList.size()) { activeThreadDumpList.add(activeThreadDump); } } } } else { for (ActiveTraceInfo activeTraceInfo : activeTraceInfoList) { TActiveThreadLightDump activeThreadDump = createActiveLightThreadDump(activeTraceInfo); if (activeThreadDump != null) { if (limit > activeThreadDumpList.size()) { activeThreadDumpList.add(activeThreadDump); } } } } return activeThreadDumpList; } private TActiveThreadLightDump createActiveLightThreadDump(ActiveTraceInfo activeTraceInfo) { Thread thread = activeTraceInfo.getThread(); if (thread == null) { return null; } TThreadLightDump threadDump = createThreadDump(thread); return createActiveThreadDump(activeTraceInfo, threadDump); } private TThreadLightDump createThreadDump(Thread thread) { TThreadLightDump threadDump = new TThreadLightDump(); threadDump.setThreadName(thread.getName()); threadDump.setThreadId(thread.getId()); threadDump.setThreadState(ThreadDumpUtils.toTThreadState(thread.getState())); return threadDump; } private TActiveThreadLightDump createActiveThreadDump(ActiveTraceInfo activeTraceInfo, TThreadLightDump threadDump) { TActiveThreadLightDump activeThreadDump = new TActiveThreadLightDump(); activeThreadDump.setStartTime(activeTraceInfo.getStartTime()); activeThreadDump.setLocalTraceId(activeTraceInfo.getLocalTraceId()); activeThreadDump.setThreadDump(threadDump); if (activeTraceInfo.isSampled()) { activeThreadDump.setSampled(true); activeThreadDump.setTransactionId(activeTraceInfo.getTransactionId()); activeThreadDump.setEntryPoint(activeTraceInfo.getEntryPoint()); } return activeThreadDump; } @Override public Class<? extends TBase> getCommandClazz() { return TCmdActiveThreadLightDump.class; } }