Merge pull request #900 from Xylus/feature/issue-84

Added backend support for agent lifecycle/event handling.
This commit is contained in:
HyunGil Jeong
2015-08-31 19:17:38 +09:00
33 changed files with 1686 additions and 346 deletions
@@ -70,8 +70,6 @@ public class DefaultRouteHandler extends AbstractRouteHandler<RequestEvent> {
}
private TCommandTransferResponse onRoute0(RequestEvent event) {
TCommandTransferResponse response = new TCommandTransferResponse();
TBase<?,?> requestObject = event.getRequestObject();
if (requestObject == null) {
return createResponse(TRouteResult.EMPTY_REQUEST);
@@ -98,12 +96,12 @@ public class DefaultRouteHandler extends AbstractRouteHandler<RequestEvent> {
return createResponse(TRouteResult.EMPTY_RESPONSE);
}
byte[] responsePayload = response.getPayload();
byte[] responsePayload = responseMessage.getMessage();
if (responsePayload == null || responsePayload.length == 0) {
return createResponse(TRouteResult.EMPTY_RESPONSE, new byte[0]);
}
return createResponse(TRouteResult.OK, responseMessage.getMessage());
return createResponse(TRouteResult.OK, responsePayload);
}
private TCommandTransferResponse createResponse(TRouteResult result) {
@@ -0,0 +1,41 @@
/*
* Copyright 2015 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.collector.cluster.route.filter;
import org.springframework.beans.factory.annotation.Autowired;
import com.navercorp.pinpoint.collector.cluster.route.ResponseEvent;
import com.navercorp.pinpoint.collector.rpc.handler.AgentEventHandler;
/**
* @author HyunGil Jeong
*/
public class AgentEventHandlingFilter implements RouteFilter<ResponseEvent> {
@Autowired
private AgentEventHandler agentEventHandler;
@Override
public void doEvent(ResponseEvent event) {
if (event == null) {
return;
}
final long eventTimestamp = System.currentTimeMillis();
this.agentEventHandler.handleResponseEvent(event, eventTimestamp);
}
}
@@ -17,31 +17,42 @@
package com.navercorp.pinpoint.collector.rpc.handler;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import javax.annotation.Resource;
import org.apache.commons.collections.MapUtils;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.navercorp.pinpoint.collector.cluster.route.ResponseEvent;
import com.navercorp.pinpoint.collector.dao.AgentEventDao;
import com.navercorp.pinpoint.collector.receiver.tcp.AgentHandshakePropertyType;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.util.AgentEventMessageSerializer;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.common.util.AgentEventTypeCategory;
import com.navercorp.pinpoint.rpc.server.PinpointServer;
import com.navercorp.pinpoint.thrift.dto.command.TCommandTransfer;
import com.navercorp.pinpoint.thrift.dto.command.TCommandTransferResponse;
import com.navercorp.pinpoint.thrift.dto.command.TRouteResult;
import com.navercorp.pinpoint.thrift.io.DeserializerFactory;
import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer;
import com.navercorp.pinpoint.thrift.util.SerializationUtils;
/**
* @author HyunGil Jeong
*/
public class AgentEventHandler {
private static final byte[] EMPTY_BODY = new byte[0];
private static final Set<AgentEventType> RESPONSE_EVENT_TYPES = AgentEventType
.getTypesByCatgory(AgentEventTypeCategory.USER_REQUEST);
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource(name="agentEventWorker")
@Resource(name = "agentEventWorker")
private Executor executor;
@Resource
@@ -49,59 +60,111 @@ public class AgentEventHandler {
@Resource
private AgentEventMessageSerializer agentEventMessageSerializer;
@Resource
private DeserializerFactory<HeaderTBaseDeserializer> commandDeserializerFactory;
public void handleEvent(PinpointServer pinpointServer, long eventTimestamp, AgentEventType eventType) {
handleEvent(pinpointServer, eventTimestamp, eventType, EMPTY_BODY);
handleEvent(pinpointServer, eventTimestamp, eventType, null);
}
public void handleEvent(PinpointServer pinpointServer, long eventTimestamp, AgentEventType eventType, Object eventMessage) {
try {
byte[] eventBody = this.agentEventMessageSerializer.serialize(eventType, eventMessage);
handleEvent(pinpointServer, eventTimestamp, eventType, eventBody);
} catch (Exception e) {
logger.warn("error serializing event message", e);
handleEvent(pinpointServer, eventTimestamp, eventType, EMPTY_BODY);
}
}
public void handleEvent(PinpointServer pinpointServer, long eventTimestamp, AgentEventType eventType, byte[] eventBody) {
public void handleEvent(PinpointServer pinpointServer, long eventTimestamp, AgentEventType eventType,
Object eventMessage) {
if (pinpointServer == null) {
throw new IllegalArgumentException("pinpointServer cannot be null");
throw new NullPointerException("pinpointServer may not be null");
}
if (eventType == null) {
throw new IllegalArgumentException("eventType cannot be null");
throw new NullPointerException("eventType may not be null");
}
Map<Object, Object> channelProperties = pinpointServer.getChannelProperties();
final String agentId = MapUtils.getString(channelProperties, AgentHandshakePropertyType.AGENT_ID.getName());
final long startTimestamp = MapUtils.getLong(channelProperties, AgentHandshakePropertyType.START_TIMESTAMP.getName());
final long startTimestamp = MapUtils.getLong(channelProperties,
AgentHandshakePropertyType.START_TIMESTAMP.getName());
final AgentEventBo agentEventBo = new AgentEventBo(agentId, startTimestamp, eventTimestamp, eventType);
if (eventBody == null) {
agentEventBo.setEventBody(EMPTY_BODY);
} else {
agentEventBo.setEventBody(eventBody);
}
logger.info("handle event - pinpointServer:{}, event:{}", pinpointServer, agentEventBo);
this.executor.execute(new AgentEventHandlerDispatch(agentEventBo));
this.executor.execute(new AgentEventHandlerDispatch(agentId, startTimestamp, eventTimestamp, eventType,
eventMessage));
}
class AgentEventHandlerDispatch implements Runnable {
private final AgentEventBo agentEventBo;
public void handleResponseEvent(ResponseEvent responseEvent, long eventTimestamp) {
if (responseEvent == null) {
throw new NullPointerException("responseEvent may not be null");
}
TCommandTransferResponse response = responseEvent.getRouteResult();
if (response.getRouteResult() != TRouteResult.OK) {
return;
}
this.executor.execute(new AgentResponseEventHandlerDispatch(responseEvent, eventTimestamp));
}
private AgentEventHandlerDispatch(AgentEventBo agentEventBo) {
if (agentEventBo == null) {
throw new IllegalArgumentException("agentEventBo cannot be null");
}
this.agentEventBo = agentEventBo;
private class AgentEventHandlerDispatch implements Runnable {
private final String agentId;
private final long startTimestamp;
private final long eventTimestamp;
private final AgentEventType eventType;
private final Object eventMessage;
private AgentEventHandlerDispatch(String agentId, long startTimestamp, long eventTimestamp,
AgentEventType eventType, Object eventMessage) {
this.agentId = agentId;
this.startTimestamp = startTimestamp;
this.eventTimestamp = eventTimestamp;
this.eventType = eventType;
this.eventMessage = eventMessage;
}
@Override
public void run() {
agentEventDao.insert(this.agentEventBo);
AgentEventBo event = new AgentEventBo(this.agentId, this.startTimestamp,
this.eventTimestamp, this.eventType);
try {
byte[] eventBody = agentEventMessageSerializer.serialize(this.eventType, this.eventMessage);
event.setEventBody(eventBody);
} catch (Exception e) {
logger.warn("error handling agent event", e);
return;
}
logger.info("handle event: {}", event);
agentEventDao.insert(event);
}
}
private class AgentResponseEventHandlerDispatch implements Runnable {
private final String agentId;
private final long startTimestamp;
private final long eventTimestamp;
private final byte[] payload;
private AgentResponseEventHandlerDispatch(ResponseEvent responseEvent, long eventTimestamp) {
final TCommandTransfer command = responseEvent.getDeliveryCommand();
this.agentId = command.getAgentId();
this.startTimestamp = command.getStartTime();
this.eventTimestamp = eventTimestamp;
final TCommandTransferResponse response = responseEvent.getRouteResult();
this.payload = response.getPayload();
}
@Override
public void run() {
Class<?> payloadType = Void.class;
if (this.payload != null) {
try {
payloadType = SerializationUtils.deserialize(this.payload, commandDeserializerFactory).getClass();
} catch (TException e) {
logger.warn("Error deserializing ResponseEvent payload", e);
return;
}
}
for (AgentEventType eventType : RESPONSE_EVENT_TYPES) {
if (eventType.getMessageType() == payloadType) {
AgentEventBo agentEventBo = new AgentEventBo(this.agentId, this.startTimestamp,
this.eventTimestamp, eventType);
agentEventBo.setEventBody(this.payload);
agentEventDao.insert(agentEventBo);
}
}
}
}
@@ -16,6 +16,8 @@
package com.navercorp.pinpoint.collector.rpc.handler;
import static com.navercorp.pinpoint.collector.receiver.tcp.AgentHandshakePropertyType.*;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -27,7 +29,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.navercorp.pinpoint.collector.dao.AgentLifeCycleDao;
import com.navercorp.pinpoint.collector.receiver.tcp.AgentHandshakePropertyType;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
import com.navercorp.pinpoint.common.util.BytesUtils;
@@ -44,36 +45,39 @@ public class AgentLifeCycleHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource(name="agentEventWorker")
@Resource(name = "agentEventWorker")
private Executor executor;
@Autowired
private AgentLifeCycleDao agentLifeCycleDao;
public void handleLifeCycleEvent(PinpointServer pinpointServer, long eventTimestamp, AgentLifeCycleState agentLifeCycleState, int eventCounter) {
public void handleLifeCycleEvent(PinpointServer pinpointServer, long eventTimestamp,
AgentLifeCycleState agentLifeCycleState, int eventCounter) {
if (pinpointServer == null) {
throw new IllegalArgumentException("pinpointServer cannot be null");
throw new NullPointerException("pinpointServer may not be null");
}
if (agentLifeCycleState == null) {
throw new IllegalArgumentException("agentLifeCycleState cannot be null");
throw new NullPointerException("agentLifeCycleState may not be null");
}
if (eventCounter < 0) {
throw new IllegalArgumentException("eventCounter cannot be negative");
throw new IllegalArgumentException("eventCounter may not be negative");
}
logger.info("handle lifecycle event - pinpointServer:{}, state:{}", pinpointServer, agentLifeCycleState);
Map<Object, Object> channelProperties = pinpointServer.getChannelProperties();
final Integer socketId = MapUtils.getInteger(channelProperties, SOCKET_ID_KEY);
if (socketId == null) {
logger.debug("socketId not found, agent does not support life cycle management - pinpoingServer:{}", pinpointServer);
logger.debug("socketId not found, agent does not support life cycle management - pinpointServer:{}",
pinpointServer);
return;
}
final String agentId = MapUtils.getString(channelProperties, AgentHandshakePropertyType.AGENT_ID.getName());
final long startTimestamp = MapUtils.getLong(channelProperties, AgentHandshakePropertyType.START_TIMESTAMP.getName());
final String agentId = MapUtils.getString(channelProperties, AGENT_ID.getName());
final long startTimestamp = MapUtils.getLong(channelProperties, START_TIMESTAMP.getName());
final long eventIdentifier = createEventIdentifier(socketId, eventCounter);
final AgentLifeCycleBo agentLifeCycleBo = new AgentLifeCycleBo(agentId, startTimestamp, eventTimestamp, eventIdentifier, agentLifeCycleState);
final AgentLifeCycleBo agentLifeCycleBo = new AgentLifeCycleBo(agentId, startTimestamp, eventTimestamp,
eventIdentifier, agentLifeCycleState);
this.executor.execute(new AgentLifeCycleHandlerDispatch(agentLifeCycleBo));
@@ -81,10 +85,10 @@ public class AgentLifeCycleHandler {
long createEventIdentifier(int socketId, int eventCounter) {
if (socketId < 0) {
throw new IllegalArgumentException("socketId cannot be less than 0");
throw new IllegalArgumentException("socketId may not be less than 0");
}
if (eventCounter < 0) {
throw new IllegalArgumentException("eventCounter cannot be less than 0");
throw new IllegalArgumentException("eventCounter may not be less than 0");
}
return ((long)socketId << INTEGER_BIT_COUNT) | eventCounter;
}
@@ -94,7 +98,7 @@ public class AgentLifeCycleHandler {
private AgentLifeCycleHandlerDispatch(AgentLifeCycleBo agentLifeCycleBo) {
if (agentLifeCycleBo == null) {
throw new IllegalArgumentException("agentLifeCycleBo cannot be null");
throw new NullPointerException("agentLifeCycleBo may not be null");
}
this.agentLifeCycleBo = agentLifeCycleBo;
}
@@ -113,6 +113,7 @@
<!-- Route Filters -->
<bean id="loggingRouteFilter" class="com.navercorp.pinpoint.collector.cluster.route.filter.LoggingFilter"/>
<bean id="agentEventHandlingFilter" class="com.navercorp.pinpoint.collector.cluster.route.filter.AgentEventHandlingFilter"/>
<!-- Filter Chains -->
<bean id="requestFilterChain" class="com.navercorp.pinpoint.collector.cluster.route.DefaultRouteFilterChain">
@@ -127,6 +128,7 @@
<constructor-arg>
<list value-type="com.navercorp.pinpoint.collector.cluster.route.filter.RouteFilter">
<ref bean="loggingRouteFilter"/>
<ref bean="agentEventHandlingFilter"/>
</list>
</constructor-arg>
</bean>
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.apache.thrift.TBase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -33,6 +34,7 @@ import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import com.google.common.util.concurrent.MoreExecutors;
import com.navercorp.pinpoint.collector.cluster.route.ResponseEvent;
import com.navercorp.pinpoint.collector.dao.AgentEventDao;
import com.navercorp.pinpoint.collector.receiver.tcp.AgentHandshakePropertyType;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
@@ -40,6 +42,12 @@ import com.navercorp.pinpoint.common.util.AgentEventMessageSerializer;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.common.util.BytesUtils;
import com.navercorp.pinpoint.rpc.server.PinpointServer;
import com.navercorp.pinpoint.thrift.dto.command.TCommandThreadDumpResponse;
import com.navercorp.pinpoint.thrift.dto.command.TCommandTransfer;
import com.navercorp.pinpoint.thrift.dto.command.TCommandTransferResponse;
import com.navercorp.pinpoint.thrift.dto.command.TRouteResult;
import com.navercorp.pinpoint.thrift.io.DeserializerFactory;
import com.navercorp.pinpoint.thrift.io.HeaderTBaseDeserializer;
/**
* @author HyunGil Jeong
@@ -58,6 +66,9 @@ public class AgentEventHandlerTest {
@Mock
private AgentEventMessageSerializer agentEventMessageSerializer;
@Mock
private DeserializerFactory<HeaderTBaseDeserializer> deserializerFactory;
@InjectMocks
private AgentEventHandler agentEventHandler = new AgentEventHandler();
@@ -86,7 +97,7 @@ public class AgentEventHandlerTest {
assertEquals(TEST_START_TIMESTAMP, actualAgentEventBo.getStartTimestamp());
assertEquals(TEST_EVENT_TIMESTAMP, actualAgentEventBo.getEventTimestamp());
assertEquals(expectedEventType, actualAgentEventBo.getEventType());
assertArrayEquals(new byte[0], actualAgentEventBo.getEventBody());
assertNull(actualAgentEventBo.getEventBody());
}
@Test
@@ -96,9 +107,11 @@ public class AgentEventHandlerTest {
final String expectedMessageBody = "test event message";
final byte[] expectedMessageBodyBytes = BytesUtils.toBytes(expectedMessageBody);
ArgumentCaptor<AgentEventBo> argCaptor = ArgumentCaptor.forClass(AgentEventBo.class);
when(this.agentEventMessageSerializer.serialize(expectedEventType, expectedMessageBody)).thenReturn(expectedMessageBodyBytes);
when(this.agentEventMessageSerializer.serialize(expectedEventType, expectedMessageBody)).thenReturn(
expectedMessageBodyBytes);
// when
this.agentEventHandler.handleEvent(this.pinpointServer, TEST_EVENT_TIMESTAMP, expectedEventType, expectedMessageBody);
this.agentEventHandler.handleEvent(this.pinpointServer, TEST_EVENT_TIMESTAMP, expectedEventType,
expectedMessageBody);
verify(this.agentEventDao, times(1)).insert(argCaptor.capture());
// then
AgentEventBo actualAgentEventBo = argCaptor.getValue();
@@ -110,22 +123,38 @@ public class AgentEventHandlerTest {
}
@Test
public void handler_should_handle_events_with_messages_of_direct_byte_array() throws Exception {
@SuppressWarnings({ "rawtypes", "unchecked" })
public void handler_should_handle_serialization_of_request_events() throws Exception {
// given
final AgentEventType expectedEventType = AgentEventType.USER_THREAD_DUMP;
final byte[] expectedMessageBody = BytesUtils.toBytes("some test message");
final TCommandThreadDumpResponse expectedThreadDumpResponse = new TCommandThreadDumpResponse();
final byte[] expectedThreadDumpResponseBody = new byte[0];
final TCommandTransfer tCommandTransfer = new TCommandTransfer();
tCommandTransfer.setAgentId(TEST_AGENT_ID);
tCommandTransfer.setStartTime(TEST_START_TIMESTAMP);
final TCommandTransferResponse tCommandTransferResponse = mock(TCommandTransferResponse.class);
when(tCommandTransferResponse.getRouteResult()).thenReturn(TRouteResult.OK);
when(tCommandTransferResponse.getPayload()).thenReturn(expectedThreadDumpResponseBody);
final ResponseEvent responseEvent = new ResponseEvent(tCommandTransfer, null, 0, tCommandTransferResponse);
ArgumentCaptor<AgentEventBo> argCaptor = ArgumentCaptor.forClass(AgentEventBo.class);
HeaderTBaseDeserializer deserializer = mock(HeaderTBaseDeserializer.class);
when(this.deserializerFactory.createDeserializer()).thenReturn(deserializer);
when(deserializer.deserialize(expectedThreadDumpResponseBody)).thenReturn((TBase)expectedThreadDumpResponse);
// when
this.agentEventHandler.handleEvent(this.pinpointServer, TEST_EVENT_TIMESTAMP, expectedEventType, expectedMessageBody);
this.agentEventHandler.handleResponseEvent(responseEvent, TEST_EVENT_TIMESTAMP);
// then
verify(this.agentEventDao, times(1)).insert(argCaptor.capture());
// then
AgentEventBo actualAgentEventBo = argCaptor.getValue();
assertEquals(TEST_AGENT_ID, actualAgentEventBo.getAgentId());
assertEquals(TEST_START_TIMESTAMP, actualAgentEventBo.getStartTimestamp());
assertEquals(TEST_EVENT_TIMESTAMP, actualAgentEventBo.getEventTimestamp());
assertEquals(expectedEventType, actualAgentEventBo.getEventType());
assertEquals(expectedMessageBody, actualAgentEventBo.getEventBody());
assertEquals(expectedThreadDumpResponseBody, actualAgentEventBo.getEventBody());
}
private static Map<Object, Object> createTestChannelProperties() {
@@ -85,6 +85,16 @@ public enum AgentEventType {
return eventType;
}
}
return OTHER;
return null;
}
public static Set<AgentEventType> getTypesByCatgory(AgentEventTypeCategory category) {
Set<AgentEventType> eventTypes = new HashSet<AgentEventType>();
for (AgentEventType eventType : AgentEventType.values()) {
if (eventType.category.contains(category)) {
eventTypes.add(eventType);
}
}
return eventTypes;
}
}
@@ -379,7 +379,7 @@ public class ApplicationMapBuilder {
ServerInstanceList serverInstanceList = builder.build();
node.setServerInstanceList(serverInstanceList);
} else if (nodeServiceType.isWas()) {
Set<AgentInfoBo> agentList = agentInfoService.selectAgent(node.getApplication().getName(), range);
Set<AgentInfoBo> agentList = agentInfoService.getAgentsByApplicationName(node.getApplication().getName(), range.getTo());
if (agentList.isEmpty()) {
logger.warn("agentInfo not found. applicationName:{}", node.getApplication());
// avoid NPE
@@ -17,14 +17,19 @@
package com.navercorp.pinpoint.web.controller;
import com.navercorp.pinpoint.web.service.AgentEventService;
import com.navercorp.pinpoint.web.service.AgentInfoService;
import com.navercorp.pinpoint.web.service.AgentStatService;
import com.navercorp.pinpoint.web.util.TimeWindow;
import com.navercorp.pinpoint.web.util.TimeWindowSlotCentricSampler;
import com.navercorp.pinpoint.web.vo.AgentEvent;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import com.navercorp.pinpoint.web.vo.AgentStat;
import com.navercorp.pinpoint.web.vo.AgentStatus;
import com.navercorp.pinpoint.web.vo.ApplicationAgentList;
import com.navercorp.pinpoint.web.vo.Range;
import com.navercorp.pinpoint.web.vo.linechart.agentstat.AgentStatChartGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -40,6 +45,7 @@ import java.util.List;
/**
* @author emeroad
* @author minwoo.jung
* @author HyunGil Jeong
*/
@Controller
public class AgentStatController {
@@ -51,6 +57,9 @@ public class AgentStatController {
@Autowired
private AgentInfoService agentInfoService;
@Autowired
private AgentEventService agentEventService;
@RequestMapping(value = "/getAgentStat", method = RequestMethod.GET)
@ResponseBody
@@ -72,12 +81,6 @@ public class AgentStatController {
logger.info("getAgentStat(agentId={}, from={}, to={}) : {}ms", agentId, from, to, watch.getLastTaskTimeMillis());
}
// FIXME dummy
// int nPoints = (int) (to - from) / 5000;
// if (sampleRate == null) {
// sampleRate = nPoints < 300 ? 1 : nPoints / 300;
// }
AgentStatChartGroup chartGroup = new AgentStatChartGroup(timeWindow);
chartGroup.addAgentStats(agentStatList);
chartGroup.buildCharts();
@@ -85,13 +88,55 @@ public class AgentStatController {
return chartGroup;
}
@RequestMapping(value = "/getAgentList", method = RequestMethod.GET)
@RequestMapping(value = "/getAgentList", method = RequestMethod.GET, params={"application", "from", "to"})
@ResponseBody
public ApplicationAgentList getApplicationAgentList(
@RequestParam("application") String applicationName,
@RequestParam("from") long from,
@RequestParam("to") long to) {
return this.getApplicationAgentList(applicationName, to);
}
@RequestMapping(value = "/getAgentList", method = RequestMethod.GET, params={"application", "timestamp"})
@ResponseBody
public ApplicationAgentList getApplicationAgentList(
@RequestParam("application") String applicationName,
@RequestParam("timestamp") long timestamp) {
return this.agentInfoService.getApplicationAgentList(applicationName, timestamp);
}
@RequestMapping(value = "/getAgentInfo", method = RequestMethod.GET)
@ResponseBody
public AgentInfo getAgentInfo(
@RequestParam("agentId") String agentId,
@RequestParam("timestamp") long timestamp) {
return this.agentInfoService.getAgentInfo(agentId, timestamp);
}
@RequestMapping(value="/getAgentStatus", method=RequestMethod.GET)
@ResponseBody
public AgentStatus getAgentStatus(
@RequestParam("agentId") String agentId,
@RequestParam("timestamp") long timestamp) {
return this.agentInfoService.getAgentStatus(agentId, timestamp);
}
@RequestMapping(value="/getAgentEvent", method=RequestMethod.GET)
@ResponseBody
public AgentEvent getAgentEvent(
@RequestParam("agentId") String agentId,
@RequestParam("eventTimestamp") long eventTimestamp,
@RequestParam("eventTypeCode") int eventTypeCode) {
return this.agentEventService.getAgentEvent(agentId, eventTimestamp, eventTypeCode);
}
@RequestMapping(value="/getAgentEvents", method=RequestMethod.GET)
@ResponseBody
public List<AgentEvent> getAgentEvents(
@RequestParam("agentId") String agentId,
@RequestParam("from") long from,
@RequestParam("to") long to) {
Range range = new Range(from, to);
return new ApplicationAgentList(agentInfoService.getApplicationAgentList(applicationName, range));
return this.agentEventService.getAgentEvents(agentId, range);
}
}
@@ -16,7 +16,6 @@
package com.navercorp.pinpoint.web.controller;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.thrift.dto.TResult;
import com.navercorp.pinpoint.thrift.dto.command.*;
import com.navercorp.pinpoint.thrift.io.DeserializerFactory;
@@ -26,6 +25,8 @@ import com.navercorp.pinpoint.thrift.io.SerializerFactory;
import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse;
import com.navercorp.pinpoint.web.server.PinpointSocketManager;
import com.navercorp.pinpoint.web.service.AgentService;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
@@ -67,7 +68,7 @@ public class CommandController {
public ModelAndView echo(@RequestParam("application") String applicationName, @RequestParam("agent") String agentId,
@RequestParam("startTimeStamp") long startTimeStamp, @RequestParam("message") String message) throws TException {
AgentInfoBo agentInfo = agentService.getAgentInfo(applicationName, agentId, startTimeStamp);
AgentInfo agentInfo = agentService.getAgentInfo(applicationName, agentId, startTimeStamp);
if (agentInfo == null) {
return createResponse(false, String.format("Can't find suitable PinpointServer(%s/%s/%d).", applicationName, agentId, startTimeStamp));
}
@@ -78,7 +79,7 @@ public class CommandController {
try {
PinpointRouteResponse pinpointRouteResponse = agentService.invoke(agentInfo, echo);
if (pinpointRouteResponse != null && pinpointRouteResponse.getRouteResult() == TRouteResult.OK) {
TBase result = pinpointRouteResponse.getResponse();
TBase<?, ?> result = pinpointRouteResponse.getResponse();
if (result == null) {
return createResponse(false, "result null.");
} else if (result instanceof TCommandEcho) {
@@ -100,7 +101,7 @@ public class CommandController {
public ModelAndView echo(@RequestParam("application") String applicationName, @RequestParam("agent") String agentId,
@RequestParam("startTimeStamp") long startTimeStamp) throws TException {
AgentInfoBo agentInfo = agentService.getAgentInfo(applicationName, agentId, startTimeStamp);
AgentInfo agentInfo = agentService.getAgentInfo(applicationName, agentId, startTimeStamp);
if (agentInfo == null) {
return createResponse(false, String.format("Can't find suitable PinpointServer(%s/%s/%d).", applicationName, agentId, startTimeStamp));
}
@@ -110,7 +111,7 @@ public class CommandController {
try {
PinpointRouteResponse pinpointRouteResponse = agentService.invoke(agentInfo, threadDump);
if (pinpointRouteResponse != null && pinpointRouteResponse.getRouteResult() == TRouteResult.OK) {
TBase result = pinpointRouteResponse.getResponse();
TBase<?, ?> result = pinpointRouteResponse.getResponse();
if (result == null) {
return createResponse(false, "result null.");
} else if (result instanceof TCommandThreadDumpResponse) {
@@ -0,0 +1,34 @@
/*
* Copyright 2015 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.web.dao;
import java.util.List;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.web.vo.Range;
/**
* @author HyunGil Jeong
*/
public interface AgentEventDao {
public AgentEventBo getAgentEvent(String agentId, long eventTimestamp, AgentEventType eventType);
public List<AgentEventBo> getAgentEvents(String agentId, Range range);
}
@@ -17,16 +17,14 @@
package com.navercorp.pinpoint.web.dao;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.web.vo.Range;
import java.util.List;
/**
* @author emeroad
* @author HyunGil Jeong
*/
public interface AgentInfoDao {
@Deprecated
AgentInfoBo findAgentInfoBeforeStartTime(String agentId, long currentTime);
List<AgentInfoBo> getAgentInfo(String agentId, Range range);
AgentInfoBo getAgentInfo(String agentId, long timestamp);
AgentInfoBo getInitialAgentInfo(String agentId);
}
@@ -0,0 +1,28 @@
/*
* Copyright 2015 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.web.dao;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
/**
* @author HyunGil Jeong
*/
public interface AgentLifeCycleDao {
AgentLifeCycleBo getAgentLifeCycle(String agentId, long timestamp);
}
@@ -0,0 +1,129 @@
/*
* Copyright 2015 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.web.dao.hbase;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.hadoop.hbase.ResultsExtractor;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.stereotype.Repository;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.hbase.HBaseTables;
import com.navercorp.pinpoint.common.hbase.HbaseOperations2;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.common.util.BytesUtils;
import com.navercorp.pinpoint.common.util.RowKeyUtils;
import com.navercorp.pinpoint.common.util.TimeUtils;
import com.navercorp.pinpoint.web.dao.AgentEventDao;
import com.navercorp.pinpoint.web.vo.Range;
/**
* @author HyunGil Jeong
*/
@Repository
public class HbaseAgentEventDao implements AgentEventDao {
private static final int SCANNER_CACHE_SIZE = 20;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private HbaseOperations2 hbaseOperations2;
@Autowired
@Qualifier("agentEventMapper")
private RowMapper<List<AgentEventBo>> agentEventMapper;
@Override
public List<AgentEventBo> getAgentEvents(String agentId, Range range) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (range == null) {
throw new NullPointerException("range must not be null");
}
Scan scan = new Scan();
scan.setMaxVersions(1);
scan.setCaching(SCANNER_CACHE_SIZE);
scan.setStartRow(createRowKey(agentId, range.getTo()));
scan.setStopRow(createRowKey(agentId, range.getFrom()));
scan.addFamily(HBaseTables.AGENT_EVENT_CF_EVENTS);
List<AgentEventBo> agentEvents = this.hbaseOperations2.find(HBaseTables.AGENT_EVENT, scan,
new AgentEventResultsExtractor());
logger.debug("agentEvents found. {}", agentEvents);
return agentEvents;
}
@Override
public AgentEventBo getAgentEvent(String agentId, long eventTimestamp, AgentEventType eventType) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (eventTimestamp < 0) {
throw new IllegalArgumentException("eventTimestamp must not be less than 0");
}
if (eventType == null) {
throw new NullPointerException("eventType must not be null");
}
final byte[] rowKey = createRowKey(agentId, eventTimestamp);
byte[] qualifier = Bytes.toBytes(eventType.getCode());
List<AgentEventBo> events = this.hbaseOperations2.get(HBaseTables.AGENT_EVENT, rowKey,
HBaseTables.AGENT_EVENT_CF_EVENTS, qualifier, this.agentEventMapper);
if (events == null || events.isEmpty()) {
return null;
}
return events.get(0);
}
private byte[] createRowKey(String agentId, long timestamp) {
byte[] agentIdKey = BytesUtils.toBytes(agentId);
long reverseTimestamp = TimeUtils.reverseTimeMillis(timestamp);
return RowKeyUtils.concatFixedByteAndLong(agentIdKey, HBaseTables.AGENT_NAME_MAX_LEN, reverseTimestamp);
}
private class AgentEventResultsExtractor implements ResultsExtractor<List<AgentEventBo>> {
@Override
public List<AgentEventBo> extractData(ResultScanner results) throws Exception {
List<AgentEventBo> agentEvents = new ArrayList<AgentEventBo>();
int rowNum = 0;
for (Result result : results) {
List<AgentEventBo> intermediateEvents = agentEventMapper.mapRow(result, rowNum++);
if (!intermediateEvents.isEmpty()) {
agentEvents.addAll(intermediateEvents);
}
}
return agentEvents;
}
}
}
@@ -25,7 +25,6 @@ import com.navercorp.pinpoint.common.util.BytesUtils;
import com.navercorp.pinpoint.common.util.RowKeyUtils;
import com.navercorp.pinpoint.common.util.TimeUtils;
import com.navercorp.pinpoint.web.dao.AgentInfoDao;
import com.navercorp.pinpoint.web.vo.Range;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
@@ -35,11 +34,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.hadoop.hbase.ResultsExtractor;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
/**
* @author emeroad
* @author HyunGil Jeong
*/
@Repository
public class HbaseAgentInfoDao implements AgentInfoDao {
@@ -53,151 +50,105 @@ public class HbaseAgentInfoDao implements AgentInfoDao {
private ServiceTypeRegistryService registry;
/**
* get a unique id based on agentId and startTime
* @param agentId
* @param range
* @return
*/
@Override
public List<AgentInfoBo> getAgentInfo(final String agentId, final Range range) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (range == null) {
throw new NullPointerException("range must not be null");
}
logger.debug("get agentInfo with, agentId={}, {}", agentId, range);
Scan scan = new Scan();
scan.setCaching(20);
long fromTime = TimeUtils.reverseTimeMillis(range.getTo());
long toTime = TimeUtils.reverseTimeMillis(1);
byte[] agentIdBytes = Bytes.toBytes(agentId);
byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, fromTime);
byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, toTime);
scan.setStartRow(startKeyBytes);
scan.setStopRow(endKeyBytes);
scan.addFamily(HBaseTables.AGENTINFO_CF_INFO);
List<AgentInfoBo> found = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor<List<AgentInfoBo>>() {
@Override
public List<AgentInfoBo> extractData(ResultScanner results) throws Exception {
final List<AgentInfoBo> result = new ArrayList<AgentInfoBo>();
int found = 0;
for (Result next : results) {
found++;
byte[] row = next.getRow();
long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN);
long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime);
byte[] serializedAgentInfo = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER);
byte[] serializedServerMetaData = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_SERVER_META_DATA);
logger.debug("found={}, {}, start={}", found, range, startTime);
if (found > 1 && startTime <= range.getFrom()) {
logger.debug("stop finding agentInfo.");
break;
}
final AgentInfoBo.Builder agentInfoBoBuilder = new AgentInfoBo.Builder(serializedAgentInfo);
agentInfoBoBuilder.setAgentId(agentId);
agentInfoBoBuilder.setStartTime(startTime);
// TODO fix
agentInfoBoBuilder.setServiceType(registry.findServiceType(agentInfoBoBuilder.getServiceTypeCode()));
if (serializedServerMetaData != null) {
agentInfoBoBuilder.setServerMetaData(new ServerMetaDataBo.Builder(serializedServerMetaData).build());
}
final AgentInfoBo agentInfoBo = agentInfoBoBuilder.build();
logger.debug("found agentInfoBo {}", agentInfoBo);
result.add(agentInfoBo);
}
logger.debug("extracted agentInfoBo {}", result);
return result;
}
});
logger.debug("get agentInfo result, {}", found);
return found;
}
/**
* find the closest agent startTime from current time
* Returns the information of the agent with its start time closest to the given timestamp
*
* @param agentId
* @param currentTime
* @param timestamp
* @return
*/
@Override
@Deprecated
public AgentInfoBo findAgentInfoBeforeStartTime(final String agentId, final long currentTime) {
public AgentInfoBo getAgentInfo(final String agentId, final long timestamp) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
// TODO need to be cached
Scan scan = createScan(agentId, currentTime);
AgentInfoBo agentInfoBo = hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new ResultsExtractor<AgentInfoBo>() {
@Override
public AgentInfoBo extractData(ResultScanner results) throws Exception {
for (Result next : results) {
byte[] row = next.getRow();
long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN);
long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime);
logger.debug("agent:{} startTime value {}", agentId, startTime);
// should find just BEFORE the start time
if (startTime < currentTime) {
byte[] serializedAgentInfo = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER);
byte[] serializedServerMetaData = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_SERVER_META_DATA);
final AgentInfoBo.Builder agentInfoBoBuilder = new AgentInfoBo.Builder(serializedAgentInfo);
agentInfoBoBuilder.setAgentId(agentId);
agentInfoBoBuilder.setStartTime(startTime);
// TODO fix
agentInfoBoBuilder.setServiceType(registry.findServiceType(agentInfoBoBuilder.getServiceTypeCode()));
if (serializedServerMetaData != null) {
agentInfoBoBuilder.setServerMetaData(new ServerMetaDataBo.Builder(serializedServerMetaData).build());
}
final AgentInfoBo agentInfoBo = agentInfoBoBuilder.build();
logger.debug("agent:{} startTime find {}", agentId, startTime);
return agentInfoBo;
}
}
logger.warn("agentInfo not found. agentId={}, time={}", agentId, currentTime);
return null;
}
});
// if (startTime == null) {
// return -1;
// }
return agentInfoBo;
Scan scan = createScan(agentId, timestamp);
scan.setMaxVersions(1);
scan.setCaching(1);
AgentInfoBo result = this.hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new AgentInfoBoResultsExtractor(agentId));
if (result == null) {
logger.warn("agentInfo not found. agentId={}, time={}", agentId, timestamp);
}
return result;
}
/**
* Returns the very first information of the agent
*
* @param agentId
*/
@Override
public AgentInfoBo getInitialAgentInfo(final String agentId) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
Scan scan = new Scan();
byte[] agentIdBytes = Bytes.toBytes(agentId);
byte[] reverseStartKey = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, Long.MAX_VALUE);
scan.setStartRow(reverseStartKey);
scan.setReversed(true);
scan.setMaxVersions(1);
scan.setCaching(1);
AgentInfoBo result = this.hbaseOperations2.find(HBaseTables.AGENTINFO, scan, new AgentInfoBoResultsExtractor(agentId));
if (result == null) {
logger.warn("agentInfo not found. agentId={}, time={}", agentId, 0);
}
return result;
}
private Scan createScan(String agentInfo, long currentTime) {
private Scan createScan(String agentId, long currentTime) {
Scan scan = new Scan();
scan.setCaching(20);
byte[] agentIdBytes = Bytes.toBytes(agentInfo);
byte[] agentIdBytes = Bytes.toBytes(agentId);
long startTime = TimeUtils.reverseTimeMillis(currentTime);
byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, startTime);
scan.setStartRow(startKeyBytes);
byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, Long.MAX_VALUE);
scan.setStartRow(startKeyBytes);
scan.setStopRow(endKeyBytes);
scan.addFamily(HBaseTables.AGENTINFO_CF_INFO);
return scan;
}
private class AgentInfoBoResultsExtractor implements ResultsExtractor<AgentInfoBo> {
private final String agentId;
private AgentInfoBoResultsExtractor(String agentId) {
this.agentId = agentId;
}
@Override
public AgentInfoBo extractData(ResultScanner results) throws Exception {
for (Result next : results) {
byte[] row = next.getRow();
long reverseStartTime = BytesUtils.bytesToLong(row, HBaseTables.AGENT_NAME_MAX_LEN);
long startTime = TimeUtils.recoveryTimeMillis(reverseStartTime);
byte[] serializedAgentInfo = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_IDENTIFIER);
byte[] serializedServerMetaData = next.getValue(HBaseTables.AGENTINFO_CF_INFO, HBaseTables.AGENTINFO_CF_INFO_SERVER_META_DATA);
final AgentInfoBo.Builder agentInfoBoBuilder = new AgentInfoBo.Builder(serializedAgentInfo);
agentInfoBoBuilder.setAgentId(this.agentId);
agentInfoBoBuilder.setStartTime(startTime);
// TODO fix
agentInfoBoBuilder.setServiceType(registry.findServiceType(agentInfoBoBuilder.getServiceTypeCode()));
if (serializedServerMetaData != null) {
agentInfoBoBuilder.setServerMetaData(new ServerMetaDataBo.Builder(serializedServerMetaData).build());
}
final AgentInfoBo agentInfoBo = agentInfoBoBuilder.build();
logger.debug("agent:{} startTime value {}", agentId, startTime);
return agentInfoBo;
}
return null;
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2015 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.web.dao.hbase;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.hadoop.hbase.ResultsExtractor;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.stereotype.Repository;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
import com.navercorp.pinpoint.common.hbase.HBaseTables;
import com.navercorp.pinpoint.common.hbase.HbaseOperations2;
import com.navercorp.pinpoint.common.util.RowKeyUtils;
import com.navercorp.pinpoint.common.util.TimeUtils;
import com.navercorp.pinpoint.web.dao.AgentLifeCycleDao;
/**
* @author HyunGil Jeong
*/
@Repository
public class HbaseAgentLifeCycleDao implements AgentLifeCycleDao {
private static final int NUM_LIFE_CYCLES_TO_SCAN = 1;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private HbaseOperations2 hbaseOperations2;
@Autowired
@Qualifier("agentLifeCycleMapper")
private RowMapper<AgentLifeCycleBo> agentLifeCycleMapper;
@Override
public AgentLifeCycleBo getAgentLifeCycle(String agentId, long timestamp) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (timestamp < 0) {
throw new IllegalArgumentException("timestamp must not be less than 0");
}
Scan scan = new Scan();
scan.setMaxVersions(1);
scan.setCaching(NUM_LIFE_CYCLES_TO_SCAN);
long fromTime = TimeUtils.reverseTimeMillis(timestamp);
byte[] agentIdBytes = Bytes.toBytes(agentId);
byte[] startKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, fromTime);
byte[] endKeyBytes = RowKeyUtils.concatFixedByteAndLong(agentIdBytes, HBaseTables.AGENT_NAME_MAX_LEN, Long.MAX_VALUE);
scan.setStartRow(startKeyBytes);
scan.setStopRow(endKeyBytes);
scan.addColumn(HBaseTables.AGENT_LIFECYCLE_CF_STATUS, HBaseTables.AGENT_LIFECYCLE_CF_STATUS_QUALI_STATES);
try {
List<AgentLifeCycleBo> agentLifeCycles = this.hbaseOperations2.find(HBaseTables.AGENT_LIFECYCLE, scan, new AgentLifeCycleResultsExtractor());
if (agentLifeCycles.isEmpty()) {
logger.debug("agentLifeCycle not found for agentId={}, timestamp={}", agentId, timestamp);
return null;
}
AgentLifeCycleBo latestLifeCycle = agentLifeCycles.get(0);
logger.debug("agentLifeCycle found for agentId={}, timestamp={}, value={}", agentId, timestamp, latestLifeCycle);
return latestLifeCycle;
} catch (Exception e) {
logger.warn("could not retrieve agentLifeCycle for agentId={}, timestamp={}", agentId, timestamp);
return null;
}
}
private class AgentLifeCycleResultsExtractor implements ResultsExtractor<List<AgentLifeCycleBo>> {
@Override
public List<AgentLifeCycleBo> extractData(ResultScanner results) throws Exception {
int found = 0;
List<AgentLifeCycleBo> agentLifeCycles = new ArrayList<AgentLifeCycleBo>();
for (Result result : results) {
agentLifeCycles.add(agentLifeCycleMapper.mapRow(result, found++));
if (found >= NUM_LIFE_CYCLES_TO_SCAN) {
break;
}
}
return agentLifeCycles;
}
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2015 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.web.mapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.Result;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.stereotype.Component;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.buffer.Buffer;
import com.navercorp.pinpoint.common.buffer.FixedBuffer;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.common.util.BytesUtils;
/**
* @author HyunGil Jeong
*/
@Component
public class AgentEventMapper implements RowMapper<List<AgentEventBo>> {
@Override
public List<AgentEventBo> mapRow(Result result, int rowNum) throws Exception {
if (result.isEmpty()) {
return Collections.emptyList();
}
List<AgentEventBo> agentEvents = new ArrayList<AgentEventBo>();
for (Cell cell : result.rawCells()) {
byte[] qualifier = CellUtil.cloneQualifier(cell);
final AgentEventType eventType = AgentEventType.getTypeByCode(BytesUtils.bytesToInt(qualifier, 0));
byte[] value = CellUtil.cloneValue(cell);
final Buffer buffer = new FixedBuffer(value);
final int version = buffer.readInt();
switch (version) {
case 0 :
final String agentId = buffer.readPrefixedString();
final long startTimestamp = buffer.readLong();
final long eventTimestamp = buffer.readLong();
final byte[] eventMessage = buffer.readPrefixedBytes();
final AgentEventBo agentEvent = new AgentEventBo(version, agentId, startTimestamp, eventTimestamp, eventType);
agentEvent.setEventBody(eventMessage);
agentEvents.add(agentEvent);
break;
default :
break;
}
}
return agentEvents;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2015 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.web.mapper;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.client.Result;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.stereotype.Component;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
import com.navercorp.pinpoint.common.buffer.Buffer;
import com.navercorp.pinpoint.common.buffer.FixedBuffer;
import com.navercorp.pinpoint.common.hbase.HBaseTables;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
/**
* @author HyunGil Jeong
*/
@Component
public class AgentLifeCycleMapper implements RowMapper<AgentLifeCycleBo> {
@Override
public AgentLifeCycleBo mapRow(Result result, int rowNum) throws Exception {
if (result.isEmpty()) {
return null;
}
Cell valueCell = result.getColumnLatestCell(HBaseTables.AGENT_LIFECYCLE_CF_STATUS, HBaseTables.AGENT_LIFECYCLE_CF_STATUS_QUALI_STATES);
return createAgentLifeCycleBo(valueCell);
}
private AgentLifeCycleBo createAgentLifeCycleBo(Cell valueCell) {
if (valueCell == null) {
return null;
}
byte[] value = CellUtil.cloneValue(valueCell);
final Buffer buffer = new FixedBuffer(value);
final int version = buffer.readInt();
switch (version) {
case 0 :
final String agentId = buffer.readPrefixedString();
final long startTimestamp = buffer.readLong();
final long eventTimestamp = buffer.readLong();
final long eventIdentifier = buffer.readLong();
final AgentLifeCycleState agentLifeCycleState = AgentLifeCycleState.getStateByCode(buffer.readShort());
final AgentLifeCycleBo agentLifeCycleBo = new AgentLifeCycleBo(agentId, startTimestamp, eventTimestamp, eventIdentifier, agentLifeCycleState);
return agentLifeCycleBo;
default :
return null;
}
}
}
@@ -27,6 +27,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,6 +44,7 @@ import com.navercorp.pinpoint.rpc.server.PinpointServer;
import com.navercorp.pinpoint.web.cluster.ClusterManager;
import com.navercorp.pinpoint.web.cluster.zookeeper.ZookeeperClusterManager;
import com.navercorp.pinpoint.web.config.WebConfig;
import com.navercorp.pinpoint.web.vo.AgentInfo;
/**
* @author koo.taejin
@@ -114,8 +116,8 @@ public class PinpointSocketManager {
return serverAcceptor.getWritableServerList();
}
public PinpointServer getCollector(AgentInfoBo agentInfo) {
return getCollector(agentInfo.getApplicationName(), agentInfo.getAgentId(), agentInfo.getStartTime());
public PinpointServer getCollector(AgentInfo agentInfo) {
return getCollector(agentInfo.getApplicationName(), agentInfo.getAgentId(), agentInfo.getStartTimestamp());
}
public PinpointServer getCollector(String applicationName, String agentId, long startTimeStamp) {
@@ -0,0 +1,33 @@
/*
* Copyright 2015 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.web.service;
import java.util.List;
import com.navercorp.pinpoint.web.vo.AgentEvent;
import com.navercorp.pinpoint.web.vo.Range;
/**
* @author HyunGil Jeong
*/
public interface AgentEventService {
AgentEvent getAgentEvent(String agentId, long eventTimestamp, int eventTypeCode);
List<AgentEvent> getAgentEvents(String agentId, Range range);
}
@@ -0,0 +1,104 @@
/*
* Copyright 2015 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.web.service;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.util.AgentEventMessageDeserializer;
import com.navercorp.pinpoint.common.util.AgentEventType;
import com.navercorp.pinpoint.web.dao.AgentEventDao;
import com.navercorp.pinpoint.web.vo.AgentEvent;
import com.navercorp.pinpoint.web.vo.Range;
/**
* @author HyunGil Jeong
*/
@Service
public class AgentEventServiceImpl implements AgentEventService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AgentEventDao agentEventDao;
@Autowired
private AgentEventMessageDeserializer agentEventMessageDeserializer;
@Override
public List<AgentEvent> getAgentEvents(String agentId, Range range) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
final boolean includeEventMessage = false;
List<AgentEventBo> agentEventBos = this.agentEventDao.getAgentEvents(agentId, range);
List<AgentEvent> agentEvents = new ArrayList<AgentEvent>(agentEventBos.size());
for (AgentEventBo agentEventBo : agentEventBos) {
if (agentEventBo != null) {
agentEvents.add(createAgentEvent(agentEventBo, includeEventMessage));
}
}
Collections.sort(agentEvents, AgentEvent.EVENT_TIMESTAMP_DESC_COMPARATOR);
return agentEvents;
}
@Override
public AgentEvent getAgentEvent(String agentId, long eventTimestamp, int eventTypeCode) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (eventTimestamp < 0) {
throw new IllegalArgumentException("eventTimeTimestamp must not be less than 0");
}
final AgentEventType eventType = AgentEventType.getTypeByCode(eventTypeCode);
if (eventType == null) {
throw new IllegalArgumentException("invalid eventTypeCode [" + eventTypeCode + "]");
}
final boolean includeEventMessage = true;
AgentEventBo agentEventBo = this.agentEventDao.getAgentEvent(agentId, eventTimestamp, eventType);
if (agentEventBo != null) {
return createAgentEvent(agentEventBo, includeEventMessage);
}
return null;
}
private AgentEvent createAgentEvent(AgentEventBo agentEventBo, boolean includeEventMessage) {
final String agentId = agentEventBo.getAgentId();
final long eventTimestamp = agentEventBo.getEventTimestamp();
final AgentEventType eventType = agentEventBo.getEventType();
AgentEvent agentEvent = new AgentEvent(agentId, eventTimestamp, eventType);
agentEvent.setStartTimestamp(agentEventBo.getStartTimestamp());
if (includeEventMessage) {
try {
agentEvent.setEventMessage(this.agentEventMessageDeserializer.deserialize(eventType,
agentEventBo.getEventBody()));
} catch (UnsupportedEncodingException e) {
logger.warn("error deserializing event message", e);
}
}
return agentEvent;
}
}
@@ -16,19 +16,23 @@
package com.navercorp.pinpoint.web.service;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.web.vo.Range;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import com.navercorp.pinpoint.web.vo.AgentStatus;
import com.navercorp.pinpoint.web.vo.ApplicationAgentList;
/**
* @author netspider
* @author HyunGil Jeong
*/
public interface AgentInfoService {
SortedMap<String, List<AgentInfoBo>> getApplicationAgentList(String applicationName, Range range);
ApplicationAgentList getApplicationAgentList(String applicationName, long timestamp);
Set<AgentInfoBo> getAgentsByApplicationName(String applicationName, long timestamp);
AgentInfo getAgentInfo(String agentId, long timestamp);
Set<AgentInfoBo> selectAgent(String applicationId, Range range);
AgentStatus getAgentStatus(String agentId, long timestamp);
}
@@ -19,9 +19,14 @@ package com.navercorp.pinpoint.web.service;
import java.util.*;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
import com.navercorp.pinpoint.web.dao.AgentInfoDao;
import com.navercorp.pinpoint.web.dao.AgentLifeCycleDao;
import com.navercorp.pinpoint.web.dao.ApplicationIndexDao;
import com.navercorp.pinpoint.web.vo.Range;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import com.navercorp.pinpoint.web.vo.AgentStatus;
import com.navercorp.pinpoint.web.vo.ApplicationAgentList;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
@@ -32,7 +37,7 @@ import org.springframework.stereotype.Service;
/**
*
* @author netspider
*
* @author HyunGil Jeong
*/
@Service
public class AgentInfoServiceImpl implements AgentInfoService {
@@ -45,73 +50,117 @@ public class AgentInfoServiceImpl implements AgentInfoService {
@Autowired
private AgentInfoDao agentInfoDao;
/**
* FIXME from/to present in the interface but these values are not currently used. They should be used when agent list snapshot is implemented
*/
@Autowired
private AgentLifeCycleDao agentLifeCycleDao;
@Override
public SortedMap<String, List<AgentInfoBo>> getApplicationAgentList(String applicationName, Range range) {
public ApplicationAgentList getApplicationAgentList(String applicationName, long timestamp) {
if (applicationName == null) {
throw new NullPointerException("applicationName must not be null");
}
final List<String> agentIdList = applicationIndexDao.selectAgentIds(applicationName);
final List<String> agentIdList = this.applicationIndexDao.selectAgentIds(applicationName);
if (logger.isDebugEnabled()) {
logger.debug("agentIdList={}", agentIdList);
}
if (CollectionUtils.isEmpty(agentIdList)) {
logger.debug("agentIdList is empty. applicationName={}, {}", applicationName, range);
return new TreeMap<String, List<AgentInfoBo>>();
logger.debug("agentIdList is empty. applicationName={}", applicationName);
return new ApplicationAgentList(new TreeMap<String, List<AgentInfo>>());
}
// key = hostname
// value= list fo agentinfo
SortedMap<String, List<AgentInfoBo>> result = new TreeMap<String, List<AgentInfoBo>>();
SortedMap<String, List<AgentInfo>> result = new TreeMap<String, List<AgentInfo>>();
for (String agentId : agentIdList) {
List<AgentInfoBo> agentInfoList = agentInfoDao.getAgentInfo(agentId, range);
AgentInfoBo agentInfoBo = this.agentInfoDao.getAgentInfo(agentId, timestamp);
if (agentInfoList.isEmpty()) {
logger.debug("agentinfolist is empty. agentid={}, {}", agentId, range);
if (agentInfoBo == null) {
continue;
}
final AgentInfo agentInfo = new AgentInfo(agentInfoBo);
final AgentStatus currentStatus = this.getAgentStatus(agentId, Long.MAX_VALUE);
agentInfo.setStatus(currentStatus);
final AgentInfoBo initialAgentInfo = this.agentInfoDao.getInitialAgentInfo(agentId);
if (initialAgentInfo != null) {
agentInfo.setInitialStartTimestamp(initialAgentInfo.getStartTime());
}
// FIXME just using the first value for now. Might need to check and pick which one to use.
AgentInfoBo agentInfo = agentInfoList.get(0);
String hostname = agentInfo.getHostName();
String hostname = agentInfoBo.getHostName();
if (result.containsKey(hostname)) {
result.get(hostname).add(agentInfo);
} else {
List<AgentInfoBo> list = new ArrayList<AgentInfoBo>();
List<AgentInfo> list = new ArrayList<AgentInfo>();
list.add(agentInfo);
result.put(hostname, list);
}
}
for (List<AgentInfoBo> agentInfoBoList : result.values()) {
Collections.sort(agentInfoBoList, AgentInfoBo.AGENT_NAME_ASC_COMPARATOR);
for (List<AgentInfo> agentInfoList : result.values()) {
Collections.sort(agentInfoList, AgentInfo.AGENT_NAME_ASC_COMPARATOR);
}
logger.info("getApplicationAgentList={}", result);
return result;
return new ApplicationAgentList(result);
}
public Set<AgentInfoBo> selectAgent(String applicationId, Range range) {
if (applicationId == null) {
throw new NullPointerException("applicationId must not be null");
@Override
public Set<AgentInfoBo> getAgentsByApplicationName(String applicationName, long timestamp) {
if (applicationName == null) {
throw new NullPointerException("applicationName must not be null");
}
List<String> agentIds = applicationIndexDao.selectAgentIds(applicationId);
List<String> agentIds = this.applicationIndexDao.selectAgentIds(applicationName);
Set<AgentInfoBo> agentSet = new HashSet<AgentInfoBo>();
for (String agentId : agentIds) {
// TODO Temporarily scans for the most recent AgentInfo row starting from range's to value.
// (As we do not yet have a way to accurately record the agent's lifecycle.)
AgentInfoBo info = agentInfoDao.findAgentInfoBeforeStartTime(agentId, range.getTo());
AgentInfoBo info = this.agentInfoDao.getAgentInfo(agentId, timestamp);
if (info != null) {
agentSet.add(info);
}
}
return agentSet;
}
@Override
public AgentInfo getAgentInfo(String agentId, long timestamp) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (timestamp < 0) {
throw new IllegalArgumentException("timestamp must not be less than 0");
}
AgentInfoBo agentInfoBo = this.agentInfoDao.getAgentInfo(agentId, timestamp);
if (agentInfoBo == null) {
return null;
}
AgentInfo agentInfo = new AgentInfo(agentInfoBo);
agentInfo.setStatus(this.getAgentStatus(agentId, timestamp));
return agentInfo;
}
@Override
public AgentStatus getAgentStatus(String agentId, long timestamp) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (timestamp < 0) {
throw new IllegalArgumentException("timestamp must not be less than 0");
}
AgentLifeCycleBo agentLifeCycleBo = this.agentLifeCycleDao.getAgentLifeCycle(agentId, timestamp);
if (agentLifeCycleBo == null) {
AgentStatus agentStatus = new AgentStatus();
agentStatus.setAgentId(agentId);
agentStatus.setState(AgentLifeCycleState.UNKNOWN);
return agentStatus;
} else {
return new AgentStatus(agentLifeCycleBo);
}
}
}
@@ -19,9 +19,10 @@
package com.navercorp.pinpoint.web.service;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse;
import com.navercorp.pinpoint.web.vo.AgentActiveThreadStatusList;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
@@ -33,21 +34,21 @@ import java.util.Map;
*/
public interface AgentService {
AgentInfoBo getAgentInfo(String applicationName, String agentId, long startTimeStamp);
AgentInfoBo getAgentInfo(String applicationName, String agentId, long startTimeStamp, boolean checkDB);
List<AgentInfoBo> getAgentInfoList(String applicationName);
AgentInfo getAgentInfo(String applicationName, String agentId, long startTimeStamp);
AgentInfo getAgentInfo(String applicationName, String agentId, long startTimeStamp, boolean checkDB);
List<AgentInfo> getAgentInfoList(String applicationName);
PinpointRouteResponse invoke(AgentInfoBo agentInfoList, TBase tBase) throws TException;
PinpointRouteResponse invoke(AgentInfoBo agentInfoList, TBase tBase, long timeout) throws TException;
PinpointRouteResponse invoke(AgentInfoBo agentInfoList, byte[] payload) throws TException;
PinpointRouteResponse invoke(AgentInfoBo agentInfoList, byte[] payload, long timeout) throws TException;
PinpointRouteResponse invoke(AgentInfo agentInfoList, TBase<?, ?> tBase) throws TException;
PinpointRouteResponse invoke(AgentInfo agentInfoList, TBase<?, ?> tBase, long timeout) throws TException;
PinpointRouteResponse invoke(AgentInfo agentInfoList, byte[] payload) throws TException;
PinpointRouteResponse invoke(AgentInfo agentInfoList, byte[] payload, long timeout) throws TException;
Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, TBase tBase) throws TException;
Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, TBase tBase, long timeout) throws TException;
Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, byte[] payload) throws TException;
Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, byte[] payload, long timeout) throws TException;
Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, TBase<?, ?> tBase) throws TException;
Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, TBase<?, ?> tBase, long timeout) throws TException;
Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, byte[] payload) throws TException;
Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, byte[] payload, long timeout) throws TException;
AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfoBo> agentInfoList) throws TException;
AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfoBo> agentInfoList, byte[] payload) throws TException;
AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfo> agentInfoList) throws TException;
AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfo> agentInfoList, byte[] payload) throws TException;
}
@@ -39,7 +39,8 @@ import com.navercorp.pinpoint.web.cluster.PinpointRouteResponse;
import com.navercorp.pinpoint.web.server.PinpointSocketManager;
import com.navercorp.pinpoint.web.vo.AgentActiveThreadStatus;
import com.navercorp.pinpoint.web.vo.AgentActiveThreadStatusList;
import com.navercorp.pinpoint.web.vo.Range;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import org.apache.thrift.TBase;
import org.apache.thrift.TException;
import org.slf4j.Logger;
@@ -51,6 +52,7 @@ import java.util.*;
/**
* @Author Taejin Koo
* @author HyunGil Jeong
*/
@Service
public class AgentServiceImpl implements AgentService {
@@ -72,17 +74,16 @@ public class AgentServiceImpl implements AgentService {
@Override
public AgentInfoBo getAgentInfo(String applicationName, String agentId, long startTimeStamp) {
public AgentInfo getAgentInfo(String applicationName, String agentId, long startTimeStamp) {
return getAgentInfo(applicationName, agentId, startTimeStamp, false);
}
@Override
public AgentInfoBo getAgentInfo(String applicationName, String agentId, long startTimeStamp, boolean checkDB) {
public AgentInfo getAgentInfo(String applicationName, String agentId, long startTimeStamp, boolean checkDB) {
if (checkDB) {
long currentTime = System.currentTimeMillis();
Range range = new Range(currentTime, currentTime);
Set<AgentInfoBo> agentInfoBos = agentInfoService.selectAgent(applicationName, range);
Set<AgentInfoBo> agentInfoBos = agentInfoService.getAgentsByApplicationName(applicationName, currentTime);
for (AgentInfoBo agentInfo : agentInfoBos) {
if (agentInfo == null) {
continue;
@@ -97,51 +98,50 @@ public class AgentServiceImpl implements AgentService {
continue;
}
return agentInfo;
return new AgentInfo(agentInfo);
}
return null;
} else {
AgentInfoBo.Builder builder = new AgentInfoBo.Builder();
builder.setApplicationName(applicationName);
builder.setAgentId(agentId);
builder.setStartTime(startTimeStamp);
return builder.build();
AgentInfo agentInfo = new AgentInfo();
agentInfo.setApplicationName(applicationName);
agentInfo.setAgentId(agentId);
agentInfo.setStartTimestamp(startTimeStamp);
return agentInfo;
}
}
@Override
public List<AgentInfoBo> getAgentInfoList(String applicationName) {
List<AgentInfoBo> agentInfoList = new ArrayList<AgentInfoBo>();
public List<AgentInfo> getAgentInfoList(String applicationName) {
List<AgentInfo> agentInfoList = new ArrayList<AgentInfo>();
long currentTime = System.currentTimeMillis();
Range range = new Range(currentTime, currentTime);
Set<AgentInfoBo> agentInfoBos = agentInfoService.selectAgent(applicationName, range);
for (AgentInfoBo agentInfo : agentInfoBos) {
ListUtils.addIfValueNotNull(agentInfoList, agentInfo);
Set<AgentInfoBo> agentInfoBos = agentInfoService.getAgentsByApplicationName(applicationName, currentTime);
for (AgentInfoBo agentInfoBo : agentInfoBos) {
ListUtils.addIfValueNotNull(agentInfoList, new AgentInfo(agentInfoBo));
}
return agentInfoList;
}
@Override
public PinpointRouteResponse invoke(AgentInfoBo agentInfo, TBase tBase) throws TException {
public PinpointRouteResponse invoke(AgentInfo agentInfo, TBase<?, ?> tBase) throws TException {
byte[] payload = serialize(tBase);
return invoke(agentInfo, payload);
}
@Override
public PinpointRouteResponse invoke(AgentInfoBo agentInfo, TBase tBase, long timeout) throws TException {
public PinpointRouteResponse invoke(AgentInfo agentInfo, TBase<?, ?> tBase, long timeout) throws TException {
byte[] payload = serialize(tBase);
return invoke(agentInfo, payload, timeout);
}
@Override
public PinpointRouteResponse invoke(AgentInfoBo agentInfo, byte[] payload) throws TException {
public PinpointRouteResponse invoke(AgentInfo agentInfo, byte[] payload) throws TException {
return invoke(agentInfo, payload, DEFUALT_FUTURE_TIMEOUT);
}
@Override
public PinpointRouteResponse invoke(AgentInfoBo agentInfo, byte[] payload, long timeout) throws TException {
public PinpointRouteResponse invoke(AgentInfo agentInfo, byte[] payload, long timeout) throws TException {
TCommandTransfer transferObject = createCommandTransferObject(agentInfo, payload);
PinpointServer collector = pinpointSocketManager.getCollector(agentInfo);
@@ -151,26 +151,26 @@ public class AgentServiceImpl implements AgentService {
}
@Override
public Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, TBase tBase) throws TException {
public Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, TBase<?, ?> tBase) throws TException {
byte[] payload = serialize(tBase);
return invoke(agentInfoList, payload);
}
@Override
public Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, TBase tBase, long timeout) throws TException {
public Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, TBase<?, ?> tBase, long timeout) throws TException {
byte[] payload = serialize(tBase);
return invoke(agentInfoList, payload, timeout);
}
@Override
public Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, byte[] payload) throws TException {
public Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, byte[] payload) throws TException {
return invoke(agentInfoList, payload, DEFUALT_FUTURE_TIMEOUT);
}
@Override
public Map<AgentInfoBo, PinpointRouteResponse> invoke(List<AgentInfoBo> agentInfoList, byte[] payload, long timeout) throws TException {
Map<AgentInfoBo, Future<ResponseMessage>> futureMap = new HashMap<AgentInfoBo, Future<ResponseMessage>>();
for (AgentInfoBo agentInfo : agentInfoList) {
public Map<AgentInfo, PinpointRouteResponse> invoke(List<AgentInfo> agentInfoList, byte[] payload, long timeout) throws TException {
Map<AgentInfo, Future<ResponseMessage>> futureMap = new HashMap<AgentInfo, Future<ResponseMessage>>();
for (AgentInfo agentInfo : agentInfoList) {
TCommandTransfer transferObject = createCommandTransferObject(agentInfo, payload);
PinpointServer collector = pinpointSocketManager.getCollector(agentInfo);
Future<ResponseMessage> future = collector.request(serialize(transferObject));
@@ -179,9 +179,9 @@ public class AgentServiceImpl implements AgentService {
long startTime = System.currentTimeMillis();
Map<AgentInfoBo, PinpointRouteResponse> result = new HashMap<AgentInfoBo, PinpointRouteResponse>();
for (Map.Entry<AgentInfoBo, Future<ResponseMessage>> futureEntry : futureMap.entrySet()) {
AgentInfoBo agentInfo = futureEntry.getKey();
Map<AgentInfo, PinpointRouteResponse> result = new HashMap<AgentInfo, PinpointRouteResponse>();
for (Map.Entry<AgentInfo, Future<ResponseMessage>> futureEntry : futureMap.entrySet()) {
AgentInfo agentInfo = futureEntry.getKey();
Future<ResponseMessage> future = futureEntry.getValue();
PinpointRouteResponse response = getResponse(future, getTimeoutMillis(startTime, timeout));
result.put(agentInfo, response);
@@ -191,18 +191,18 @@ public class AgentServiceImpl implements AgentService {
}
@Override
public AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfoBo> agentInfoList) throws TException {
public AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfo> agentInfoList) throws TException {
byte[] activeThread = serialize(new TActiveThread());
return getActiveThreadStatus(agentInfoList, activeThread);
}
@Override
public AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfoBo> agentInfoList, byte[] payload) throws TException {
public AgentActiveThreadStatusList getActiveThreadStatus(List<AgentInfo> agentInfoList, byte[] payload) throws TException {
AgentActiveThreadStatusList agentActiveThreadStatusList = new AgentActiveThreadStatusList(agentInfoList.size());
Map<AgentInfoBo, PinpointRouteResponse> responseList = invoke(agentInfoList, payload);
for (Map.Entry<AgentInfoBo, PinpointRouteResponse> entry : responseList.entrySet()) {
AgentInfoBo agentInfo = entry.getKey();
Map<AgentInfo, PinpointRouteResponse> responseList = invoke(agentInfoList, payload);
for (Map.Entry<AgentInfo, PinpointRouteResponse> entry : responseList.entrySet()) {
AgentInfo agentInfo = entry.getKey();
PinpointRouteResponse response = entry.getValue();
AgentActiveThreadStatus agentActiveThreadStatus = new AgentActiveThreadStatus(agentInfo.getHostName(), response.getRouteResult(), response.getResponse(TActiveThreadResponse.class, null));
@@ -211,23 +211,23 @@ public class AgentServiceImpl implements AgentService {
return agentActiveThreadStatusList;
}
private byte[] serialize(TBase tBase) throws TException {
private byte[] serialize(TBase<?, ?> tBase) throws TException {
return SerializationUtils.serialize(tBase, commandSerializerFactory);
}
private TBase deserialize(byte[] objectData) throws TException {
private TBase<?, ?> deserialize(byte[] objectData) throws TException {
return SerializationUtils.deserialize(objectData, commandDeserializerFactory);
}
private TBase deserialize(byte[] objectData, TBase defaultValue) throws TException {
private TBase<?, ?> deserialize(byte[] objectData, TBase<?, ?> defaultValue) throws TException {
return SerializationUtils.deserialize(objectData, commandDeserializerFactory, defaultValue);
}
private TCommandTransfer createCommandTransferObject(AgentInfoBo agentInfo, byte[] payload) {
private TCommandTransfer createCommandTransferObject(AgentInfo agentInfo, byte[] payload) {
TCommandTransfer transferObject = new TCommandTransfer();
transferObject.setApplicationName(agentInfo.getApplicationName());
transferObject.setAgentId(agentInfo.getAgentId());
transferObject.setStartTime(agentInfo.getStartTime());
transferObject.setStartTime(agentInfo.getStartTimestamp());
transferObject.setPayload(payload);
return transferObject;
@@ -0,0 +1,40 @@
/*
* Copyright 2015 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.web.view;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
/**
* @author HyunGil Jeong
*/
public class AgentLifeCycleStateSerializer extends JsonSerializer<AgentLifeCycleState> {
@Override
public void serialize(AgentLifeCycleState value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("code", value.getCode());
jgen.writeStringField("desc", value.getDesc());
jgen.writeEndObject();
}
}
@@ -20,10 +20,13 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
import com.navercorp.pinpoint.web.applicationmap.link.MatcherGroup;
import com.navercorp.pinpoint.web.applicationmap.link.ServerMatcher;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import com.navercorp.pinpoint.web.vo.AgentStatus;
import com.navercorp.pinpoint.web.vo.ApplicationAgentList;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
@@ -32,48 +35,58 @@ import java.util.Map;
/**
* @author minwoo.jung
* @author HyunGil Jeong
*/
public class ApplicationAgentListSerializer extends JsonSerializer<ApplicationAgentList> {
@Autowired(required=false)
@Autowired(required = false)
private MatcherGroup matcherGroup;
@Override
public void serialize(ApplicationAgentList applicationAgentList, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
public void serialize(ApplicationAgentList applicationAgentList, JsonGenerator jgen, SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
Map<String, List<AgentInfoBo>> map = applicationAgentList.getApplicationAgentList();
for (Map.Entry<String, List<AgentInfoBo>> entry : map.entrySet()) {
Map<String, List<AgentInfo>> map = applicationAgentList.getApplicationAgentList();
for (Map.Entry<String, List<AgentInfo>> entry : map.entrySet()) {
jgen.writeFieldName(entry.getKey());
writeAgentList(jgen, entry.getValue(), getMatcherGroup());
}
jgen.writeEndObject();
}
private void writeAgentList(JsonGenerator jgen, List<AgentInfoBo> agentList, MatcherGroup matcherGroup) throws IOException {
private void writeAgentList(JsonGenerator jgen, List<AgentInfo> agentList, MatcherGroup matcherGroup) throws IOException {
jgen.writeStartArray();
for (AgentInfoBo agentInfoBo : agentList) {
for (AgentInfo agentInfo : agentList) {
jgen.writeStartObject();
jgen.writeStringField("hostName", agentInfoBo.getHostName());
jgen.writeStringField("ip", agentInfoBo.getIp());
jgen.writeStringField("ports", agentInfoBo.getPorts());
jgen.writeStringField("agentId", agentInfoBo.getAgentId());
jgen.writeStringField("applicationName", agentInfoBo.getApplicationName());
jgen.writeStringField("serviceType", agentInfoBo.getServiceType().toString());
jgen.writeNumberField("pid", agentInfoBo.getPid());
jgen.writeStringField("version", agentInfoBo.getVersion());
jgen.writeNumberField("startTime", agentInfoBo.getStartTime());
jgen.writeNumberField("endTimeStamp", agentInfoBo.getEndTimeStamp());
jgen.writeNumberField("endStatus", agentInfoBo.getEndStatus());
jgen.writeObjectField("serverMetaData", agentInfoBo.getServerMetaData());
jgen.writeStringField("applicationName", agentInfo.getApplicationName());
jgen.writeStringField("agentId", agentInfo.getAgentId());
jgen.writeNumberField("startTime", agentInfo.getStartTimestamp());
jgen.writeStringField("hostName", agentInfo.getHostName());
jgen.writeStringField("ip", agentInfo.getIp());
jgen.writeStringField("ports", agentInfo.getPorts());
jgen.writeStringField("serviceType", agentInfo.getServiceType().toString());
jgen.writeNumberField("pid", agentInfo.getPid());
jgen.writeStringField("version", agentInfo.getVersion());
jgen.writeObjectField("serverMetaData", agentInfo.getServerMetaData());
AgentStatus agentStatus = agentInfo.getStatus();
if (agentStatus == null) {
jgen.writeNumberField("endTimeStamp", 0);
jgen.writeStringField("endStatus", AgentLifeCycleState.UNKNOWN.getDesc());
} else {
jgen.writeNumberField("endTimeStamp", agentStatus.getEventTimestamp());
jgen.writeStringField("endStatus", agentStatus.getState().getDesc());
}
jgen.writeObjectField("status", agentStatus);
ServerMatcher serverMatcher = matcherGroup.match(agentInfoBo.getHostName());
jgen.writeNumberField("initialStartTime", agentInfo.getInitialStartTimestamp());
ServerMatcher serverMatcher = matcherGroup.match(agentInfo.getHostName());
jgen.writeStringField("linkName", serverMatcher.getLinkName());
jgen.writeStringField("linkURL", serverMatcher.getLink(agentInfoBo.getHostName()));
jgen.writeStringField("linkURL", serverMatcher.getLink(agentInfo.getHostName()));
jgen.writeEndObject();
}
jgen.writeEndArray();
@@ -0,0 +1,166 @@
/*
* Copyright 2015 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.web.vo;
import java.util.Comparator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.navercorp.pinpoint.common.util.AgentEventType;
/**
* @author HyunGil Jeong
*/
@JsonInclude(Include.NON_NULL)
public class AgentEvent {
public static final Comparator<AgentEvent> EVENT_TIMESTAMP_DESC_COMPARATOR = new Comparator<AgentEvent>() {
@Override
public int compare(AgentEvent o1, AgentEvent o2) {
int eventTimestampComparison = Long.compare(o2.eventTimestamp, o1.eventTimestamp);
if (eventTimestampComparison == 0) {
return o1.eventTypeCode - o2.eventTypeCode;
}
return eventTimestampComparison;
}
};
@JsonProperty
private final String agentId;
@JsonProperty
private final long eventTimestamp;
@JsonProperty
private final int eventTypeCode;
@JsonProperty
private final String eventTypeDesc;
@JsonProperty
private final boolean hasEventMessage;
@JsonProperty
private long startTimestamp;
@JsonProperty
private Object eventMessage;
public AgentEvent(String agentId, long eventTimestamp, AgentEventType eventType) {
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
if (eventTimestamp < 0) {
throw new IllegalArgumentException("eventTimestamp must not be null");
}
if (eventType == null) {
throw new NullPointerException("eventType must not be null");
}
this.agentId = agentId;
this.eventTimestamp = eventTimestamp;
this.eventTypeCode = eventType.getCode();
this.eventTypeDesc = eventType.getDesc();
this.hasEventMessage = eventType.getMessageType() != Void.class;
}
public String getAgentId() {
return agentId;
}
public long getEventTimestamp() {
return eventTimestamp;
}
public int getEventTypeCode() {
return eventTypeCode;
}
public String getEventTypeDesc() {
return eventTypeDesc;
}
public boolean hasEventMessage() {
return this.hasEventMessage;
}
public long getStartTimestamp() {
return startTimestamp;
}
public void setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
}
public Object getEventMessage() {
return eventMessage;
}
public void setEventMessage(Object eventMessage) {
this.eventMessage = eventMessage;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((agentId == null) ? 0 : agentId.hashCode());
result = prime * result + (int)(eventTimestamp ^ (eventTimestamp >>> 32));
result = prime * result + eventTypeCode;
result = prime * result + ((eventTypeDesc == null) ? 0 : eventTypeDesc.hashCode());
result = prime * result + (hasEventMessage ? 1231 : 1237);
result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AgentEvent other = (AgentEvent)obj;
if (agentId == null) {
if (other.agentId != null)
return false;
} else if (!agentId.equals(other.agentId))
return false;
if (eventTimestamp != other.eventTimestamp)
return false;
if (eventTypeCode != other.eventTypeCode)
return false;
if (eventTypeDesc == null) {
if (other.eventTypeDesc != null)
return false;
} else if (!eventTypeDesc.equals(other.eventTypeDesc))
return false;
if (hasEventMessage != other.hasEventMessage)
return false;
if (startTimestamp != other.startTimestamp)
return false;
return true;
}
@Override
public String toString() {
return "AgentEvent [agentId=" + agentId + ", eventTimestamp=" + eventTimestamp + ", eventTypeCode="
+ eventTypeCode + ", eventTypeDesc=" + eventTypeDesc + ", hasEventMessage=" + hasEventMessage
+ ", startTimestamp=" + startTimestamp + ", eventMessage=" + eventMessage + "]";
}
}
@@ -0,0 +1,258 @@
/*
* Copyright 2015 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.web.vo;
import java.util.Comparator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.common.bo.ServerMetaDataBo;
/**
* @author HyunGil Jeong
*/
public class AgentInfo {
public static final Comparator<AgentInfo> AGENT_NAME_ASC_COMPARATOR = new Comparator<AgentInfo>() {
@Override
public int compare(AgentInfo lhs, AgentInfo rhs) {
final String lhsAgentId = lhs.agentId == null ? "" : lhs.agentId;
final String rhsAgentId = rhs.agentId == null ? "" : rhs.agentId;
return lhsAgentId.compareTo(rhsAgentId);
}
};
private String applicationName;
private String agentId;
private long startTimestamp;
private String hostName;
private String ip;
private String ports;
private String serviceType;
private int pid;
private String version;
private ServerMetaDataBo serverMetaData;
@JsonInclude(Include.NON_DEFAULT)
private long initialStartTimestamp;
@JsonInclude(Include.NON_NULL)
private AgentStatus status;
public AgentInfo() {
}
public AgentInfo(AgentInfoBo agentInfoBo) {
this.applicationName = agentInfoBo.getApplicationName();
this.agentId = agentInfoBo.getAgentId();
this.startTimestamp = agentInfoBo.getStartTime();
this.hostName = agentInfoBo.getHostName();
this.ip = agentInfoBo.getIp();
this.ports = agentInfoBo.getPorts();
this.serviceType = agentInfoBo.getServiceType().getName();
this.pid = agentInfoBo.getPid();
this.version = agentInfoBo.getVersion();
this.serverMetaData = agentInfoBo.getServerMetaData();
}
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public long getStartTimestamp() {
return startTimestamp;
}
public void setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPorts() {
return ports;
}
public void setPorts(String ports) {
this.ports = ports;
}
public String getServiceType() {
return serviceType;
}
public void setServiceType(String serviceType) {
this.serviceType = serviceType;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public ServerMetaDataBo getServerMetaData() {
return serverMetaData;
}
public void setServerMetaData(ServerMetaDataBo serverMetaData) {
this.serverMetaData = serverMetaData;
}
public long getInitialStartTimestamp() {
return initialStartTimestamp;
}
public void setInitialStartTimestamp(long initialStartTimestamp) {
this.initialStartTimestamp = initialStartTimestamp;
}
public AgentStatus getStatus() {
return status;
}
public void setStatus(AgentStatus status) {
this.status = status;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((agentId == null) ? 0 : agentId.hashCode());
result = prime * result + ((applicationName == null) ? 0 : applicationName.hashCode());
result = prime * result + ((hostName == null) ? 0 : hostName.hashCode());
result = prime * result + (int)(initialStartTimestamp ^ (initialStartTimestamp >>> 32));
result = prime * result + ((ip == null) ? 0 : ip.hashCode());
result = prime * result + pid;
result = prime * result + ((ports == null) ? 0 : ports.hashCode());
result = prime * result + ((serverMetaData == null) ? 0 : serverMetaData.hashCode());
result = prime * result + ((serviceType == null) ? 0 : serviceType.hashCode());
result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32));
result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AgentInfo other = (AgentInfo)obj;
if (agentId == null) {
if (other.agentId != null)
return false;
} else if (!agentId.equals(other.agentId))
return false;
if (applicationName == null) {
if (other.applicationName != null)
return false;
} else if (!applicationName.equals(other.applicationName))
return false;
if (hostName == null) {
if (other.hostName != null)
return false;
} else if (!hostName.equals(other.hostName))
return false;
if (initialStartTimestamp != other.initialStartTimestamp)
return false;
if (ip == null) {
if (other.ip != null)
return false;
} else if (!ip.equals(other.ip))
return false;
if (pid != other.pid)
return false;
if (ports == null) {
if (other.ports != null)
return false;
} else if (!ports.equals(other.ports))
return false;
if (serverMetaData == null) {
if (other.serverMetaData != null)
return false;
} else if (!serverMetaData.equals(other.serverMetaData))
return false;
if (serviceType == null) {
if (other.serviceType != null)
return false;
} else if (!serviceType.equals(other.serviceType))
return false;
if (startTimestamp != other.startTimestamp)
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
@Override
public String toString() {
return "AgentInfo [applicationName=" + applicationName + ", agentId=" + agentId + ", startTimestamp=" + startTimestamp + ", hostName=" + hostName
+ ", ip=" + ip + ", ports=" + ports + ", serviceType=" + serviceType + ", pid=" + pid + ", version=" + version + ", serverMetaData="
+ serverMetaData + ", initialStartTimestamp=" + initialStartTimestamp + ", status=" + status + "]";
}
}
@@ -16,34 +16,109 @@
package com.navercorp.pinpoint.web.vo;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.navercorp.pinpoint.common.bo.AgentLifeCycleBo;
import com.navercorp.pinpoint.common.util.AgentLifeCycleState;
import com.navercorp.pinpoint.web.view.AgentLifeCycleStateSerializer;
/**
*
* @author netspider
*
* @author HyunGil Jeong
*/
public class AgentStatus {
private final boolean exists;
private final long checkTime;
private final AgentInfoBo agentInfo;
private String agentId;
public AgentStatus(AgentInfoBo agentInfoBo) {
this.exists = agentInfoBo != null;
this.agentInfo = agentInfoBo;
this.checkTime = System.currentTimeMillis();
@JsonInclude(Include.NON_DEFAULT)
private long startTimestamp;
@JsonInclude(Include.NON_DEFAULT)
private long eventTimestamp;
@JsonSerialize(using = AgentLifeCycleStateSerializer.class)
private AgentLifeCycleState state;
public AgentStatus() {
}
public boolean isExists() {
return exists;
public AgentStatus(AgentLifeCycleBo agentLifeCycleBo) {
this.agentId = agentLifeCycleBo.getAgentId();
this.startTimestamp = agentLifeCycleBo.getStartTimestamp();
this.eventTimestamp = agentLifeCycleBo.getEventTimestamp();
this.state = agentLifeCycleBo.getAgentLifeCycleState();
}
public AgentInfoBo getAgentInfo() {
return agentInfo;
public String getAgentId() {
return agentId;
}
public long getCheckTime() {
return checkTime;
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public long getStartTimestamp() {
return startTimestamp;
}
public void setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
}
public long getEventTimestamp() {
return eventTimestamp;
}
public void setEventTimestamp(long eventTimestamp) {
this.eventTimestamp = eventTimestamp;
}
public AgentLifeCycleState getState() {
return state;
}
public void setState(AgentLifeCycleState state) {
this.state = state;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((agentId == null) ? 0 : agentId.hashCode());
result = prime * result + (int)(eventTimestamp ^ (eventTimestamp >>> 32));
result = prime * result + (int)(startTimestamp ^ (startTimestamp >>> 32));
result = prime * result + ((state == null) ? 0 : state.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AgentStatus other = (AgentStatus)obj;
if (agentId == null) {
if (other.agentId != null)
return false;
} else if (!agentId.equals(other.agentId))
return false;
if (eventTimestamp != other.eventTimestamp)
return false;
if (startTimestamp != other.startTimestamp)
return false;
if (state != other.state)
return false;
return true;
}
@Override
public String toString() {
return "AgentStatus [agentId=" + agentId + ", startTimestamp=" + startTimestamp + ", eventTimestamp=" + eventTimestamp + ", state=" + state + "]";
}
}
@@ -17,7 +17,6 @@
package com.navercorp.pinpoint.web.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.web.view.ApplicationAgentListSerializer;
import java.util.List;
@@ -29,13 +28,13 @@ import java.util.SortedMap;
@JsonSerialize(using = ApplicationAgentListSerializer.class)
public class ApplicationAgentList {
SortedMap<String, List<AgentInfoBo>> applicationAgentList;
SortedMap<String, List<AgentInfo>> applicationAgentList;
public ApplicationAgentList(SortedMap<String, List<AgentInfoBo>> applicationAgentList) {
public ApplicationAgentList(SortedMap<String, List<AgentInfo>> applicationAgentList) {
this.applicationAgentList = applicationAgentList;
}
public SortedMap<String, List<AgentInfoBo>> getApplicationAgentList() {
public SortedMap<String, List<AgentInfo>> getApplicationAgentList() {
return this.applicationAgentList;
}
@@ -20,11 +20,12 @@
package com.navercorp.pinpoint.web.websocket;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.navercorp.pinpoint.common.bo.AgentInfoBo;
import com.navercorp.pinpoint.common.util.PinpointThreadFactory;
import com.navercorp.pinpoint.rpc.util.TimerFactory;
import com.navercorp.pinpoint.web.service.AgentService;
import com.navercorp.pinpoint.web.vo.AgentActiveThreadStatusList;
import com.navercorp.pinpoint.web.vo.AgentInfo;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.jboss.netty.util.Timeout;
@@ -181,7 +182,7 @@ public class ActiveThreadHandler extends TextWebSocketHandler implements Pinpoi
readLock.lock();
try {
for (Map.Entry<String, List<WebSocketSession>> applicationEntry : applicationGroup.entrySet()) {
List<AgentInfoBo> agentInfoList = agentSerivce.getAgentInfoList(applicationEntry.getKey());
List<AgentInfo> agentInfoList = agentSerivce.getAgentInfoList(applicationEntry.getKey());
AgentActiveThreadStatusList agentActiveThreadStatusList = agentSerivce.getActiveThreadStatus(agentInfoList);
String textMessage = jsonConverter.writeValueAsString(agentActiveThreadStatusList);
@@ -81,6 +81,10 @@
<bean id="pinpointSocketManager" class="com.navercorp.pinpoint.web.server.PinpointSocketManager">
<constructor-arg ref="config" />
</bean>
<bean id="agentEventMessageDeserializer" class="com.navercorp.pinpoint.common.util.AgentEventMessageDeserializer">
<constructor-arg ref="commandHeaderTBaseDeserializerFactory"/>
</bean>
<bean id="typeLoaderService" class="com.navercorp.pinpoint.common.service.DefaultTraceMetadataLoaderService"/>
<bean id="serviceTypeRegistryService" class="com.navercorp.pinpoint.common.service.DefaultServiceTypeRegistryService">