#1358 Add duration fields to agent start/shutdown events

This commit is contained in:
HyunGil Jeong
2015-12-17 13:31:39 +09:00
parent 16ef118ddd
commit a2a7e21489
5 changed files with 148 additions and 42 deletions
@@ -29,12 +29,12 @@ import com.navercorp.pinpoint.thrift.dto.command.TCommandThreadDumpResponse;
* @author HyunGil Jeong
*/
public enum AgentEventType {
AGENT_CONNECTED(10100, "Agent connected", Void.class, AGENT_LIFECYCLE),
AGENT_CONNECTED(10100, "Agent connected", Void.class, DURATIONAL, AGENT_LIFECYCLE),
AGENT_PING(10199, "Agent ping", Void.class, AGENT_LIFECYCLE),
AGENT_SHUTDOWN(10200, "Agent shutdown", Void.class, AGENT_LIFECYCLE),
AGENT_UNEXPECTED_SHUTDOWN(10201, "Agent unexpected shutdown", Void.class, AGENT_LIFECYCLE),
AGENT_CLOSED_BY_SERVER(10300, "Agent connection closed by server", Void.class, AGENT_LIFECYCLE),
AGENT_UNEXPECTED_CLOSE_BY_SERVER(10301, "Agent connection unexpectedly closed by server", Void.class, AGENT_LIFECYCLE),
AGENT_SHUTDOWN(10200, "Agent shutdown", Void.class, DURATIONAL, AGENT_LIFECYCLE),
AGENT_UNEXPECTED_SHUTDOWN(10201, "Agent unexpected shutdown", Void.class, DURATIONAL, AGENT_LIFECYCLE),
AGENT_CLOSED_BY_SERVER(10300, "Agent connection closed by server", Void.class, DURATIONAL, AGENT_LIFECYCLE),
AGENT_UNEXPECTED_CLOSE_BY_SERVER(10301, "Agent connection unexpectedly closed by server", Void.class, DURATIONAL, AGENT_LIFECYCLE),
USER_THREAD_DUMP(20100, "Thread dump by user", TCommandThreadDumpResponse.class, USER_REQUEST, THREAD_DUMP),
OTHER(-1, "Other event", String.class, AgentEventTypeCategory.OTHER);
@@ -20,6 +20,7 @@ package com.navercorp.pinpoint.common.util;
* @author HyunGil Jeong
*/
public enum AgentEventTypeCategory {
DURATIONAL,
AGENT_LIFECYCLE,
USER_REQUEST,
THREAD_DUMP,
@@ -19,8 +19,12 @@ package com.navercorp.pinpoint.web.service;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import com.navercorp.pinpoint.common.util.AgentEventTypeCategory;
import com.navercorp.pinpoint.web.vo.DurationalAgentEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -54,13 +58,8 @@ public class AgentEventServiceImpl implements AgentEventService {
}
final boolean includeEventMessage = false;
List<AgentEventBo> agentEventBos = this.agentEventDao.getAgentEvents(agentId, range);
List<AgentEvent> agentEvents = new ArrayList<>(agentEventBos.size());
for (AgentEventBo agentEventBo : agentEventBos) {
if (agentEventBo != null) {
agentEvents.add(createAgentEvent(agentEventBo, includeEventMessage));
}
}
Collections.sort(agentEvents, AgentEvent.EVENT_TIMESTAMP_DESC_COMPARATOR);
List<AgentEvent> agentEvents = createAgentEvents(agentEventBos, includeEventMessage);
Collections.sort(agentEvents, AgentEvent.EVENT_TIMESTAMP_ASC_COMPARATOR);
return agentEvents;
}
@@ -84,21 +83,54 @@ public class AgentEventServiceImpl implements AgentEventService {
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);
private List<AgentEvent> createAgentEvents(List<AgentEventBo> agentEventBos, boolean includeEventMessage) {
List<AgentEvent> agentEvents = new ArrayList<>(agentEventBos.size());
PriorityQueue<DurationalAgentEvent> durationalAgentEvents = new PriorityQueue<>(agentEventBos.size(), AgentEvent.EVENT_TIMESTAMP_ASC_COMPARATOR);
for (AgentEventBo agentEventBo : agentEventBos) {
if (agentEventBo.getEventType().isCategorizedAs(AgentEventTypeCategory.DURATIONAL)) {
durationalAgentEvents.add(createDurationalAgentEvent(agentEventBo, includeEventMessage));
} else {
agentEvents.add(createAgentEvent(agentEventBo, includeEventMessage));
}
}
long durationStartTimestamp = DurationalAgentEvent.UNKNOWN_TIMESTAMP;
while (!durationalAgentEvents.isEmpty()) {
DurationalAgentEvent currentEvent = durationalAgentEvents.remove();
currentEvent.setDurationStartTimestamp(durationStartTimestamp);
DurationalAgentEvent nextEvent = durationalAgentEvents.peek();
if (nextEvent != null) {
long nextEventTimestamp = nextEvent.getEventTimestamp();
currentEvent.setDurationEndTimestamp(nextEventTimestamp);
durationStartTimestamp = nextEventTimestamp;
}
agentEvents.add(currentEvent);
}
return agentEvents;
}
private AgentEvent createAgentEvent(AgentEventBo agentEventBo, boolean includeEventMessage) {
AgentEvent agentEvent = new AgentEvent(agentEventBo);
if (includeEventMessage) {
agentEvent.setEventMessage(deserializeEventMessage(agentEventBo));
}
return agentEvent;
}
private DurationalAgentEvent createDurationalAgentEvent(AgentEventBo agentEventBo, boolean includeEventMessage) {
DurationalAgentEvent durationalAgentEvent = new DurationalAgentEvent(agentEventBo);
if (includeEventMessage) {
durationalAgentEvent.setEventMessage(deserializeEventMessage(agentEventBo));
}
return durationalAgentEvent;
}
private Object deserializeEventMessage(AgentEventBo agentEventBo) {
try {
return this.agentEventMessageDeserializer.deserialize(agentEventBo.getEventType(), agentEventBo.getEventBody());
} catch (UnsupportedEncodingException e) {
logger.warn("error deserializing event message", e);
return null;
}
}
}
@@ -21,6 +21,7 @@ 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.bo.AgentEventBo;
import com.navercorp.pinpoint.common.util.AgentEventType;
/**
@@ -29,6 +30,17 @@ import com.navercorp.pinpoint.common.util.AgentEventType;
@JsonInclude(Include.NON_NULL)
public class AgentEvent {
public static final Comparator<AgentEvent> EVENT_TIMESTAMP_ASC_COMPARATOR = new Comparator<AgentEvent>() {
@Override
public int compare(AgentEvent o1, AgentEvent o2) {
int eventTimestampComparison = Long.compare(o1.eventTimestamp, o2.eventTimestamp);
if (eventTimestampComparison == 0) {
return o2.eventTypeCode - o1.eventTypeCode;
}
return eventTimestampComparison;
}
};
public static final Comparator<AgentEvent> EVENT_TIMESTAMP_DESC_COMPARATOR = new Comparator<AgentEvent>() {
@Override
public int compare(AgentEvent o1, AgentEvent o2) {
@@ -56,23 +68,16 @@ public class AgentEvent {
private final boolean hasEventMessage;
@JsonProperty
private long startTimestamp;
private final 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;
public AgentEvent(AgentEventBo agentEventBo) {
this.agentId = agentEventBo.getAgentId();
this.eventTimestamp = agentEventBo.getEventTimestamp();
this.startTimestamp = agentEventBo.getStartTimestamp();
AgentEventType eventType = agentEventBo.getEventType();
this.eventTypeCode = eventType.getCode();
this.eventTypeDesc = eventType.getDesc();
this.hasEventMessage = eventType.getMessageType() != Void.class;
@@ -102,10 +107,6 @@ public class AgentEvent {
return startTimestamp;
}
public void setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
}
public Object getEventMessage() {
return eventMessage;
}
@@ -161,6 +162,6 @@ public class AgentEvent {
public String toString() {
return "AgentEvent [agentId=" + agentId + ", eventTimestamp=" + eventTimestamp + ", eventTypeCode="
+ eventTypeCode + ", eventTypeDesc=" + eventTypeDesc + ", hasEventMessage=" + hasEventMessage
+ ", startTimestamp=" + startTimestamp + ", eventMessage=" + eventMessage + "]";
+ ", eventMessage=" + eventMessage + ", startTimestamp=" + startTimestamp + "]";
}
}
@@ -0,0 +1,72 @@
/*
* 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 com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.navercorp.pinpoint.common.bo.AgentEventBo;
import com.navercorp.pinpoint.common.util.AgentEventType;
/**
* @author HyunGil Jeong
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DurationalAgentEvent extends AgentEvent {
public static final long UNKNOWN_TIMESTAMP = -1;
@JsonProperty
private long durationStartTimestamp = UNKNOWN_TIMESTAMP;
@JsonProperty
private long durationEndTimestamp = UNKNOWN_TIMESTAMP;
public DurationalAgentEvent(AgentEventBo agentEventBo) {
super(agentEventBo);
}
public long getDurationStartTimestamp() {
return this.durationStartTimestamp;
}
public void setDurationStartTimestamp(long durationStartTimestamp) {
this.durationStartTimestamp = durationStartTimestamp;
}
public long getDurationEndTimestamp() {
return this.durationEndTimestamp;
}
public void setDurationEndTimestamp(long durationEndTimestamp) {
this.durationEndTimestamp = durationEndTimestamp;
}
@Override
public String toString() {
return "DurationalAgentEvent{" +
"agentId=" + super.getAgentId() +
", eventTimestamp=" + super.getEventTimestamp() +
", eventTypeCode=" + super.getEventTypeCode() +
", eventTypeDesc=" + super.getEventTypeDesc() +
", hasEventMessage=" + super.hasEventMessage() +
", eventMessage=" + super.getEventMessage() +
", startTimestamp=" + super.getStartTimestamp() +
", durationStartTimestamp=" + durationStartTimestamp +
", durationEndTimestamp=" + durationEndTimestamp +
'}';
}
}