translated comments to English

This commit is contained in:
Xylus
2014-12-30 19:44:19 +09:00
parent 685d802844
commit 3be5caeb06
45 changed files with 213 additions and 230 deletions
@@ -28,7 +28,7 @@ import com.navercorp.pinpoint.common.buffer.Buffer;
import com.navercorp.pinpoint.common.buffer.OffsetFixedBuffer;
/**
* value filter보다 column name에 prefix 붙여 filter하는것이 나을 듯하여 일단 deprecated 처리 함.
* @deprecated it is better to filter by adding prefix to the column name, than to filter by value
*
* @author netspider
*
@@ -50,7 +50,7 @@ public class ApplicationTraceIndexResponseTimeFilter extends FilterBase {
@Override
public void reset() {
// 새로운 값을 비교할 때마다 플래그 재설정.
// reset flag when comparing with a new value
this.filterRow = true;
}
@@ -63,17 +63,17 @@ public class ApplicationTraceIndexResponseTimeFilter extends FilterBase {
int elapsed = valueBuffer.readVarInt();
if (elapsed < responseTimeFrom || elapsed > responseTimeTo) {
// 조건에 맞지 않으면 row를 통과
// skip row if conditions are not met
filterRow = false;
}
// 실제 결정은 나중에 하기 때문에 항상 이 값을 반환
// always return this value as the actual decision for filtering happens later
return ReturnCode.INCLUDE;
}
@Override
public boolean filterRow() {
// 실제 결정은 플래그 상태에 따라 이곳에서 이루어진다.
// the actual decision for filtering happens here depending on the flag
return filterRow;
}
@@ -120,7 +120,7 @@ public class AnnotationTranscoder {
} else if (o instanceof Short) {
return CODE_SHORT;
} else if (o instanceof Float) {
// thrift에서 지원안함.
// not supported by thrift
return CODE_FLOAT;
} else if (o instanceof Double) {
return CODE_DOUBLE;
@@ -201,7 +201,7 @@ public class AnnotationTranscoder {
final TIntStringValue tIntStringValue = (TIntStringValue) value;
final int intValue = tIntStringValue.getIntValue();
final byte[] stringValue = BytesUtils.toBytes(tIntStringValue.getStringValue());
// 대충 크기 더함. 나중에 좀더 정교하게 계산하자.
// TODO increase by a more precise value
final int bufferSize = getBufferSize(stringValue, 4 + 8);
final Buffer buffer = new AutomaticBuffer(bufferSize);
buffer.putSVar(intValue);
@@ -230,7 +230,7 @@ public class AnnotationTranscoder {
final int intValue = tIntStringStringValue.getIntValue();
final byte[] stringValue1 = BytesUtils.toBytes(tIntStringStringValue.getStringValue1());
final byte[] stringValue2 = BytesUtils.toBytes(tIntStringStringValue.getStringValue2());
// 대충 크기 더함. 나중에 좀더 정교하게 계산하자.
// TODO increase by a more precise value
final int bufferSize = getBufferSize(stringValue1, stringValue2, 4 + 8);
final Buffer buffer = new AutomaticBuffer(bufferSize);
buffer.putSVar(intValue);
@@ -61,19 +61,19 @@ public final class AnnotationUtils {
}
public static AnnotationBo getDisplayArgument(Span span) {
// arcus 관련 일반화 필요.
// TODO needs a more generalized implementation for Arcus
List<AnnotationBo> list = span.getAnnotationBoList();
if (list == null) {
return null;
}
final ServiceType serviceType = span.getServiceType();
if (serviceType == ServiceType.ARCUS || serviceType == ServiceType.MEMCACHED) {
// 첫번째 args아무거나 하나를 디스플레이에 뿌린다.
// TODO 2개 이상일 경우의 케이스 일때 비기는 하나, 현재 arucs쪽 파라미터 덤프키는 일단 1개뿐이라 괜찮을듯하다.
// Displays any value within the first argument.
// TODO Values may be missing when there are 2+ parameters - since there is only 1 parameter dump key for Arcus, it migth be okay for now.
return findArgsAnnotationBo(list);
}
// rpc connector의 경우 보여주는 code일반화 필요.
// TODO needs a more generalized implementation for rpc connectors
if (serviceType == ServiceType.HTTP_CLIENT || serviceType == ServiceType.JDK_HTTPURLCONNECTOR) {
return findAnnotationBo(list, AnnotationKey.HTTP_URL);
}
@@ -86,18 +86,18 @@ public final class AnnotationUtils {
return findAnnotationBo(list, AnnotationKey.CAll_URL);
}
// span에 해당하는 Tomcat의 경우 Span에 포함된 rpc 필드를 사용하므로 annotation에서 찾을필요가 없음.
// For Tomcat spans, there is no need to lookup using annotation as they can just use the rpc field within the Span
// if (span.getServiceType() == ServiceType.TOMCAT) {
// return findAnnotationBo(list, AnnotationKey.HTTP_URL);
// }
//
// TODO 먼가 고쳐야 함.
// TODO something needs fixing
if (serviceType == ServiceType.MYSQL || serviceType == ServiceType.MYSQL_EXECUTE_QUERY
|| serviceType == ServiceType.ORACLE || serviceType == ServiceType.ORACLE_EXECUTE_QUERY
|| serviceType == ServiceType.MSSQL || serviceType == ServiceType.MSSQL_EXECUTE_QUERY
|| serviceType == ServiceType.CUBRID || serviceType == ServiceType.CUBRID_EXECUTE_QUERY) {
// args 0의 경우 연결string이다
// 구현 방법이 매우 구림 좀더 개선 필요.
// args0 is a string
// TODO needs better implementation
return findAnnotationBo(list, AnnotationKey.ARGS0);
}
@@ -135,6 +135,7 @@ public final class AnnotationUtils {
}
}
// 정확한 에러 코드를 못찾음. 퉁쳐서 에러 처리
// could not find a more specific error - returns generalized error
return AnnotationKey.ERROR_API_METADATA_ERROR;
}
@@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory;
import java.util.regex.Pattern;
/**
* MethodDescriptor 과 비슷한데. 문자열을 기반으로 parsing하여 생성하므로 따로 만들었음.
* Similar to MethodDescriptor, but instead parses string-based values.
* @author emeroad
*/
public class ApiDescriptionParser {
@@ -69,7 +69,7 @@ public class ApiDescriptionParser {
api.setSimpleParameter(simpleParameterList);
int lineIndex = apiDescriptionString.lastIndexOf(':');
// 일단 땜방으로 lineNumber체크해서 lineNumber를 뿌려주도록 하자.
// TODO for now, check and display the lineNumber
if (lineIndex != -1) {
try {
int line = Integer.parseInt(apiDescriptionString.substring(lineIndex + 1, apiDescriptionString.length()));
@@ -96,7 +96,7 @@ public class ApiDescriptionParser {
private String simepleParameter(String parameter) {
int packageIndex = parameter.lastIndexOf(DOT);
if (packageIndex == -1) {
// 없을 경우 아래 로직가 동일하나 추후 뭔가 변경사항이 생길수 있어 명시적으로 체크하는 로직으로 구현.
// same logic as below (-1 + 1 == 0) - explicitly checks as there may be changes in the future.
packageIndex = 0;
} else {
packageIndex += 1;
@@ -49,7 +49,7 @@ public final class ClassLoaderUtils {
} catch (Throwable ignore) {
// skip
}
// 파라미터로 ClassLoader를 전달 받으면 security exception 의 발생타이밍이 다르다.
// Timing for security exceptions is different when the ClassLoader is received as an argument
return defaultClassLoaderCallable.getClassLoader();
}
@@ -63,7 +63,7 @@ public class DefaultParsingResult implements ParsingResult {
}
/**
* 최초 한번은 불려야 된다 안불리고 appendOutputParam을 호출하면 nullpointer exception
* Must be invoked at least once. If not, generates a NullPointerException upon invoking appendOutputParam.
*/
void appendOutputSeparator() {
if (output == null) {
@@ -19,8 +19,6 @@ package com.navercorp.pinpoint.common.util;
/**
* @author emeroad
*/
//@Component
// spring 디펜던시를 걸어야 되서 그냥 안함.
public class DefaultTimeSlot implements TimeSlot {
private static final long ONE_MIN_RESOLUTION = 60000; // 1min
@@ -37,7 +35,7 @@ public class DefaultTimeSlot implements TimeSlot {
@Override
public long getTimeSlot(long time) {
// 과거 time을 기준으로 얻어오나, 모두 동일하게 과거 시간의 슬롯을 얻어오게 되므로 + RESOLUTION을 하지 않아도 된다.
// not necessary to add ONE_MIN_RESOLUTION as all the timeslots are based on the start value of the given time.
return (time / resolution) * resolution;
}
}
@@ -34,15 +34,15 @@ public final class HttpUtils {
public static String parseContentTypeCharset(String contentType, String defaultCharset) {
if (contentType == null) {
// 스펙상으로는 iso-8859-1 이나 요즘 대부분 was에서 UTF-8 고치기 때문에 애매하다. 옵션 설정에서 고칠수 있게 해야 될지도 모름.
// default spec specifies iso-8859-1, but most WASes set it to UTF-8.
// might be better to make it configurable
return defaultCharset;
}
int charsetStart = contentType.indexOf(CHARSET);
if (charsetStart == -1) {
// 없음.
// none
return defaultCharset;
}
// 요기가 시작점.
charsetStart = charsetStart + CHARSET.length();
int charsetEnd = contentType.indexOf(';', charsetStart);
if (charsetEnd == -1) {
@@ -78,8 +78,8 @@ public final class NetUtils {
}
/**
* 가지고 있는 외부에서 접근할수 있는 ip를 모두 반환합니다.
* 만약 로컬 ip가 획득하지 못할 경우 Empty List를 반환합니다.
* Returns a list of ip addreses on this machine that is accessible from a remote source.
* If no network interfaces can be found on this machine, returns an empty List.
*/
public static List<String> getLocalV4IpList() {
List<String> result = new ArrayList<String>();
@@ -28,7 +28,7 @@ public class OutputParameterParser {
public static final char SEPARATOR = DefaultParsingResult.SEPARATOR;
public List<String> parseOutputParameter(String outputParams) {
// 추가적으로 parsing result를 알수 있어야 될거 같음.
// may also need to know about the parsing result
if (outputParams == null || outputParams.length() == 0) {
return Collections.emptyList();
}
@@ -43,7 +43,6 @@ public final class RowKeyUtils {
public static byte[] getMetaInfoRowKey(String agentId, long agentStartTime, int keyCode) {
// TODO 일단 agent의 조회 시간 로직을 따로 만들어야 되므로 그냥0으로 하자.
if (agentId == null) {
throw new NullPointerException("agentId must not be null");
}
@@ -81,7 +81,7 @@ public class SqlParser {
break;
}
// case '#'
// mysql 에서는 #도 한줄 짜리 comment이다.
// # is a single line comment in mysql
case '-':
// single line comment state
if (lookAhead1(sql, i) == '-') {
@@ -101,7 +101,7 @@ public class SqlParser {
// empty symbol
if (lookAhead1(sql, i) == '\'') {
normalized.append("''");
// $로 치환하지 않으므로 output에 파라미터를 넣을필요가 없다
// no need to add parameter to output as $ is not converted
i += 2;
break;
} else {
@@ -112,7 +112,7 @@ public class SqlParser {
for (; i < length; i++) {
char stateCh = sql.charAt(i);
if (stateCh == '\'') {
// '' 이 연속으로 나왔을 경우는 \' 이므로 그대로 넣는다.
// a consecutive ' is the same as \'
if (lookAhead1(sql, i) == '\'') {
i++;
parsingResult.appendOutputParam("''");
@@ -141,7 +141,7 @@ public class SqlParser {
case '7':
case '8':
case '9':
// http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것.
// http://www.h2database.com/html/grammar.html look at the state machine more
if (numberTokenStartEnable) {
change = true;
normalized.append(replaceIndex++);
@@ -170,7 +170,7 @@ public class SqlParser {
parsingResult.appendOutputParam(stateCh);
break;
default:
// 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다.
// should look at the token outside the loop - not here
// outputParam.append(SEPARATOR);
i--;
break tokenEnd;
@@ -182,7 +182,7 @@ public class SqlParser {
break;
}
// 공백 space를 만남
// empty space
case ' ':
case '\t':
case '\n':
@@ -190,7 +190,7 @@ public class SqlParser {
numberTokenStartEnable = true;
normalized.append(ch);
break;
// http://msdn.microsoft.com/en-us/library/ms174986.aspx 참조.
// http://msdn.microsoft.com/en-us/library/ms174986.aspx
case '*':
case '+':
case '%':
@@ -217,13 +217,13 @@ public class SqlParser {
case '.':
case '_':
case '@': // Assignment Operator
case ':': // 오라클쪽의 bind 변수는 :bindvalue로도 가능.
case ':': // Oracle's bind variable is possible with :bindvalue
numberTokenStartEnable = false;
normalized.append(ch);
break;
default:
// 한글이면 ??
// what if it's in a different language??
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
numberTokenStartEnable = false;
} else {
@@ -237,9 +237,9 @@ public class SqlParser {
parsingResult.setSql(normalized.toString());
return parsingResult;
} else {
// 수정되지 않았을 경우의 재활용.
// 1. 성능향상을 위해 string을 생성하지 않도록.
// 2. hash code재활용.
// Reuse if not modified.
// 1. new strings are not generated
// 2. reuse hashcodes
parsingResult.setSql(sql);
return parsingResult;
}
@@ -258,7 +258,7 @@ public class SqlParser {
}
/**
* 미리 다음 문자열 하나를 까본다.
* look up the next character in a string
*
* @param sql
* @param index
@@ -314,7 +314,7 @@ public class SqlParser {
break;
}
// case '#'
// mysql 에서는 #도 한줄 짜리 comment이다.
// # is a single line comment in mysql
case '-':
// single line comment state
if (lookAhead1(sql, i) == '-') {
@@ -340,7 +340,7 @@ public class SqlParser {
case '7':
case '8':
case '9':
// http://www.h2database.com/html/grammar.html 추가로 state machine을 더볼것.
// http://www.h2database.com/html/grammar.html look at the state machine more
if (lookAhead1(sql, i) == NEXT_TOKEN_NOT_EXIST) {
normalized.append(ch);
break;
@@ -375,7 +375,7 @@ public class SqlParser {
try {
numberIndex = Integer.parseInt(outputIndex.toString());
} catch (NumberFormatException e) {
// 잘못된 파라미터일 경우 그냥 쓰자.
// just append for invalid parameters
normalized.append(outputIndex.toString());
normalized.append(NUMBER_REPLACE);
break tokenEnd;
@@ -384,7 +384,7 @@ public class SqlParser {
String replaceNumber = outputParams.get(numberIndex);
normalized.append(replaceNumber);
} catch (IndexOutOfBoundsException e) {
// 잘못된 파라미터일 경우 그냥 쓰자.
// just append for invalid parameters
normalized.append(outputIndex.toString());
normalized.append(NUMBER_REPLACE);
break tokenEnd;
@@ -396,7 +396,7 @@ public class SqlParser {
try {
symbolIndex = Integer.parseInt(outputIndex.toString());
} catch (NumberFormatException e) {
// 잘못된 파라미터일 경우 그냥 쓰자.
// just append for invalid parameters
normalized.append(outputIndex.toString());
normalized.append(SYMBOL_REPLACE);
}
@@ -410,7 +410,7 @@ public class SqlParser {
break tokenEnd;
default:
// 여기서 처리하지 말고 루프 바깥으로 나가서 다시 token을 봐야 된다.
// should look at the token outside the loop - not here
// outputParam.append(SEPARATOR);
normalized.append(outputIndex.toString());
i--;
@@ -17,7 +17,7 @@
package com.navercorp.pinpoint.common.util;
/**
* 단순한 stopwatch
* A simple stopwatch
* @author emeroad
*/
public class StopWatch {
@@ -24,7 +24,7 @@ import com.navercorp.pinpoint.common.buffer.FixedBuffer;
* @author emeroad
*/
public final class TransactionIdUtils {
// html 에서 표시되는 값이라. html 상에서 해석이 다르게 되는 문자열은 사용하면 안됨.
// value is displayed as html - should not use html syntax
public static final String TRANSACTION_ID_DELIMITER = "^";
public static final byte VERSION = 0;
@@ -45,7 +45,7 @@ public final class TransactionIdUtils {
}
public static byte[] formatBytes(String agentId, long agentStartTime, long transactionSequence) {
// agentId는 null이 될수 있음.
// agentId may be null
// vesion + prefixed size + string + long + long
final Buffer buffer = new AutomaticBuffer(1 + 5 + 24 + 10 + 10);
buffer.put(VERSION);
@@ -94,7 +94,8 @@ public final class TransactionIdUtils {
int transactionSequenceIndex = nextIndex(transactionId, agentStartTimeIndex + 1);
if (transactionSequenceIndex == -1) {
// 이거는 없을수 있음. transactionSequence 다음에 델리미터가 일단 없는게 기본값임. 향후 추가 아이디 스펙이 확장가능하므로 보완한다.
// next index may not exist since default value does not have a delimiter after transactionSequence.
// may need fixing when id spec changes
transactionSequenceIndex = transactionId.length();
}
final long transactionSequence = parseLong(transactionId, agentStartTimeIndex + 1, transactionSequenceIndex);
@@ -128,7 +128,7 @@ public class ApplicationMapBuilder {
final Application toApplication = linkData.getToApplication();
// FROM -> TO에서 TO가 CLIENT가 아니면 TO는 node
// FROM -> TO : TO is either a CLIENT or a node
if (!toApplication.getServiceType().isRpcClient()) {
final boolean success = addNode(nodeList, toApplication);
if (success) {
@@ -187,14 +187,14 @@ public class ApplicationMapBuilder {
final Application toApplicationId = linkData.getToApplication();
Node toNode = nodeList.findNode(toApplicationId);
// rpc client가 빠진경우임.
// rpc client missing
if (toNode == null) {
logger.warn("toNode rcp client not found:{}", toApplicationId);
continue;
}
// RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경
// 여기서 RPC가 나올일이 없지 않나하는데. 먼저 앞단에서 Unknown노드로 변경시킴.
// for RPC clients: skip if there is a dest application, convert to "unknown cloud" if not
// shouldn't really be necessary as rpc client toNodes are converted to unknown nodes beforehand.
if (toNode.getServiceType().isRpcClient()) {
if (!nodeList.containsNode(toNode.getApplication())) {
final Link link = addLink(linkList, fromNode, toNode, CreateType.Source);
@@ -226,17 +226,17 @@ public class ApplicationMapBuilder {
for (LinkData linkData : linkDataMap.getLinkDataList()) {
final Application fromApplicationId = linkData.getFromApplication();
Node fromNode = nodeList.findNode(fromApplicationId);
// TODO
final Application toApplicationId = linkData.getToApplication();
Node toNode = nodeList.findNode(toApplicationId);
// rpc client가 빠진경우임.
// rpc client missing
if (fromNode == null) {
logger.warn("fromNode rcp client not found:{}", toApplicationId);
continue;
}
// RPC client인 경우 dest application이 이미 있으면 삭제, 없으면 unknown cloud로 변경.
// for RPC clients: skip if there is a dest application, convert to "unknown cloud" if not
if (toNode.getServiceType().isRpcClient()) {
// to 노드가 존재하는지 검사?
if (!nodeList.containsNode(toNode.getApplication())) {
@@ -263,7 +263,7 @@ public class ApplicationMapBuilder {
for (Node node : nodes) {
final ServiceType nodeType = node.getServiceType();
if (nodeType.isWas()) {
// was일 경우 자신의 response 히스토그램을 조회하여 채운다.
// for WAS nodes, set their own response time histogram
final Application wasNode = node.getApplication();
final NodeHistogram nodeHistogram = nodeHistogramDataSource.createNodeHistogram(wasNode);
node.setNodeHistogram(nodeHistogram);
@@ -272,7 +272,7 @@ public class ApplicationMapBuilder {
final NodeHistogram nodeHistogram = createTerminalNodeHistogram(node, linkList);
node.setNodeHistogram(nodeHistogram);
} else if (nodeType.isUser()) {
// User노드인 경우 source 링크를 찾아 histogram을 생성한다.
// for User nodes, find its source link and create the histogram
Application userNode = node.getApplication();
final NodeHistogram nodeHistogram = new NodeHistogram(userNode, range);
@@ -292,7 +292,7 @@ public class ApplicationMapBuilder {
node.setNodeHistogram(nodeHistogram);
} else {
// 그냥 데미 데이터
// dummy data
NodeHistogram dummy = new NodeHistogram(node.getApplication(), range);
node.setNodeHistogram(dummy);
}
@@ -302,11 +302,11 @@ public class ApplicationMapBuilder {
}
private NodeHistogram createTerminalNodeHistogram(Node node, LinkList linkList) {
// 터미널 노드인경우, 자신을 가리키는 link값을 합하여 histogram을 생성한다.
// for Terminal nodes, add all links pointing to iself and create the histogram
final Application nodeApplication = node.getApplication();
final NodeHistogram nodeHistogram = new NodeHistogram(nodeApplication, range);
// appclicationHistogram 생성.
// create applicationHistogram
final List<Link> toLinkList = linkList.findToLink(nodeApplication);
final Histogram applicationHistogram = new Histogram(node.getServiceType());
for (Link link : toLinkList) {
@@ -314,7 +314,7 @@ public class ApplicationMapBuilder {
}
nodeHistogram.setApplicationHistogram(applicationHistogram);
// applicationTimeHistogram 생성.
// create applicationTimeHistogram
LinkCallDataMap linkCallDataMap = new LinkCallDataMap();
for (Link link : toLinkList) {
LinkCallDataMap sourceLinkCallDataMap = link.getSourceLinkCallDataMap();
@@ -324,7 +324,7 @@ public class ApplicationMapBuilder {
ApplicationTimeHistogram applicationTimeHistogram = builder.build(linkCallDataMap.getLinkDataList());
nodeHistogram.setApplicationTimeHistogram(applicationTimeHistogram);
// terminal일 경우 node AgentLevel histogram을 추가로 생성한다.
// for Terminal nodes, create AgentLevel histogram
if (nodeApplication.getServiceType().isTerminal()) {
final Map<String, Histogram> agentHistogramMap = new HashMap<String, Histogram>();
@@ -366,12 +366,12 @@ public class ApplicationMapBuilder {
private void appendServerInfo(Node node, LinkDataDuplexMap linkDataDuplexMap, AgentInfoService agentInfoService) {
final ServiceType nodeServiceType = node.getServiceType();
if (nodeServiceType.isUnknown()) {
// unknown노드는 무엇이 설치되어있는지 알수가 없음.
// we do not know the server info for unknown nodes
return;
}
if (nodeServiceType.isTerminal()) {
// terminal노드에 설치되어 있는 정보를 유추한다.
// extract information about the terminal node
ServerBuilder builder = new ServerBuilder(matcherGroup);
for (LinkData linkData : linkDataDuplexMap.getSourceLinkDataList()) {
Application toApplication = linkData.getToApplication();
@@ -392,19 +392,19 @@ public class ApplicationMapBuilder {
builder.addAgentInfo(agentList);
ServerInstanceList serverInstanceList = builder.build();
// destination이 WAS이고 agent가 설치되어있으면 agentSet이 존재한다.
// agentSet exists if the destination is a WAS, and has agent installed
node.setServerInstanceList(serverInstanceList);
} else {
// 기타 해당 되지 않는 상황일 경우 empty 정보를 넣는다.
// add empty information
node.setServerInstanceList(new ServerInstanceList());
}
}
/**
* 실제 응답속도 정보가 있는 데이터를 기반으로 AgentInfo를 필터링 친다.
* 정공이라고 말할 수 있는 코드는 아님.
* 나중에 실제 서버가 살아 있는 정보를 기반으로 이를 유추할수 있게 해야한다.
* Filters AgentInfo by whether they actually have response data.
* This is only a temporary solution until we implement agent life cycle management.
* FIXME Use the actual agent status (once implemented) to filter out AgentInfo
*/
private Set<AgentInfoBo> filterAgentInfoByResponseData(Set<AgentInfoBo> agentList, Node node) {
Set<AgentInfoBo> filteredAgentInfo = new HashSet<AgentInfoBo>();
@@ -53,7 +53,7 @@ public class TransactionIdMapper implements RowMapper<List<TransactionId>> {
for (KeyValue kv : raw) {
byte[] buffer = kv.getBuffer();
int qualifierOffset = kv.getQualifierOffset();
// key값만큼 1증가 시킴
// increment by value of key
TransactionId traceId = parseVarTransactionId(buffer, qualifierOffset);
traceIdList.add(traceId);
@@ -62,17 +62,14 @@ public class TransactionIdMapper implements RowMapper<List<TransactionId>> {
return traceIdList;
}
// 중복시킴. TraceIndexScatterMapper랑 동일하므로 같이 변경하거나 리팩토링 할것.
// TODO : Duplicated with TraceIndexScatterMapper. you should modify both at the same time or need to refactor
public static TransactionId parseVarTransactionId(byte[] bytes, int offset) {
if (bytes == null) {
throw new NullPointerException("bytes must not be null");
}
final Buffer buffer = new OffsetFixedBuffer(bytes, offset);
// skip elapsed time (not used) hbase column prefix filter에서 filter용도로만 사용함.
// 데이터 사이즈를 줄일 수 있는지 모르겠음.
// skip elapsed time (not used) hbase column prefix - only used for filtering.
// Not sure if we can reduce the data size any further.
// buffer.readInt();
String agentId = buffer.readPrefixedString();
@@ -51,7 +51,7 @@ public class PinpointSocketManager {
private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
private final Charset charset = Charset.forName("UTF-8");
// 로컬 ip
// local ip
// @Value("#{pinpointWebProps['web.tcpListenI']}")
private String representationLocalIp;
private List<String> localIpList;
@@ -76,7 +76,7 @@ public class PinpointSocketManager {
logger.info("Representation_Ip = {}, Ip_List = {}", representationLocalIp, localIpList);
// 옵션으로 지정할수 있게 하면 좋을듯 뛰울껀지 말껀지
// TODO might be better to make it configurable whether to keep the process alive or to kill
if (representationLocalIp.equals(NetUtils.LOOPBACK_ADDRESS_V4) || localIpList.size() == 0) {
throw new SocketException("Can't find Local Ip.");
}
@@ -91,8 +91,7 @@ public class PinpointSocketManager {
this.clusterManager = new ZookeeperClusterManager(config.getClusterZookeeperAddress(), config.getClusterZookeeperSessionTimeout(), config.getClusterZookeeperRetryInterval());
// TODO 여기서 수정이 필요함
// json list는 표준규칙이 아니기 때문에 ip\r\n으로 저장
// TODO need modification - storing ip list using \r\n as delimiter since json list is not supported natively
this.clusterManager.registerWebCluster(nodeName, convertIpListToBytes(localIpList, "\r\n"));
}
}
@@ -117,12 +116,12 @@ public class PinpointSocketManager {
public ChannelContext getCollectorChannelContext(String applicationName, String agentId, long startTimeStamp) {
List<String> agentNameList = clusterManager.getRegisteredAgentList(applicationName, agentId, startTimeStamp);
// AgentName은 중복되는 경우는 문제가 있는 경우임
// having duplicate AgentName registered is an exceptional case
if (agentNameList.size() == 0) {
logger.warn("{}/{} Can't find agent.", applicationName, agentId);
logger.warn("{}/{} couldn't find agent.", applicationName, agentId);
return null;
} else if (agentNameList.size() > 1) {
logger.warn("{}/{} find dupplicate agent {}.", applicationName, agentId, agentNameList);
logger.warn("{}/{} found duplicate agent {}.", applicationName, agentId, agentNameList);
return null;
}
@@ -147,7 +146,7 @@ public class PinpointSocketManager {
return ip;
}
// LOOPBACK Addess 다 제거하고 나옴
// local ip addresses with all LOOPBACK addresses removed
List<String> ipList = NetUtils.getLocalV4IpList();
if (ipList.size() > 0) {
return ipList.get(0);
@@ -46,8 +46,7 @@ public class AgentInfoServiceImpl implements AgentInfoService {
private AgentInfoDao agentInfoDao;
/**
* FIXME 인터페이스에 from, to가 있으나 실제로 사용되지 않음. 나중에 agent list snapshot기능이 추가되면
* 사용될 것임.
* FIXME from/to present in the interface but these values are not currently used. They should be used when agent list snapshot is implemented
*/
@Override
public SortedMap<String, List<AgentInfoBo>> getApplicationAgentList(String applicationName, Range range) {
@@ -76,7 +75,7 @@ public class AgentInfoServiceImpl implements AgentInfoService {
continue;
}
// FIXME 지금은 그냥 첫 번재꺼 사용. 여러개 검사?는 나중에 생각해볼 예정.
// 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();
@@ -106,8 +105,8 @@ public class AgentInfoServiceImpl implements AgentInfoService {
List<String> agentIds = applicationIndexDao.selectAgentIds(applicationId);
Set<AgentInfoBo> agentSet = new HashSet<AgentInfoBo>();
for (String agentId : agentIds) {
// TODO 조회 시간대에 따라서 agent info row timestamp를 변경하여 조회해야하는지는 모르겠음.
// 과거에 조회하였을 경우 이를 과거 시간을 기준으로 거슬러 올라가도록 to를 넣어서 조회하도록 임시 수정.
// 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());
if (info != null) {
agentSet.add(info);
@@ -26,12 +26,6 @@ import com.navercorp.pinpoint.web.vo.Range;
*/
public interface AgentStatService {
/**
* 주어진 시간 범위에 따라 특정 agentId에 해당하는 시스템 통계 정보를 조회한다.
* @param agentId
* @param range
* @return
*/
List<AgentStat> selectAgentStatList(String agentId, Range range);
}
@@ -124,7 +124,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
LoadFactor statistics = new LoadFactor(range);
// TODO fromToFilter처럼. node의 타입에 따른 처리 필요함.
// TODO need to handle these separately by node type (like fromToFilter)
// scan transaction list
for (SpanBo span : filteredTransactionList) {
@@ -140,7 +140,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
// find exception
boolean hasException = spanEventBo.hasException();
// add sample
// TODO : 실제값 대신 slot값을 넣어야 함.
// TODO : need timeslot value instead of the actual value
statistics.addSample(span.getStartTime() + spanEventBo.getStartElapsed(), spanEventBo.getEndElapsed(), 1, hasException);
break;
}
@@ -181,7 +181,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
}
List<TransactionId> transactionIdList = new ArrayList<TransactionId>();
transactionIdList.add(transactionId);
// FIXME from,to -1 땜방임.
// FIXME from,to -1
Range range = new Range(-1, -1);
return selectApplicationMap(transactionIdList, range, range, Filter.NONE);
}
@@ -212,11 +212,11 @@ public class FilteredMapServiceImpl implements FilteredMapService {
}
private List<List<SpanBo>> selectFilteredSpan(List<TransactionId> transactionIdList, Filter filter) {
// 개별 객체를 각각 보고 재귀 내용을 삭제함.
// 향후 tree base로 충돌구간을 점검하여 없앨 경우 여기서 filter를 치면 안됨.
// filters out recursive calls by looking at each objects
// do not filter here if we change to a tree-based collision check in the future.
final Collection<TransactionId> recursiveFilterList = recursiveCallFilter(transactionIdList);
// FIXME 나중에 List<Span>을 순회하면서 실행할 process chain을 두는것도 괜찮을듯.
// FIXME might be better to simply traverse the List<Span> and create a process chain for execution
final List<List<SpanBo>> originalList = this.traceDao.selectAllSpans(recursiveFilterList);
return filterList2(originalList, filter);
@@ -224,7 +224,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
private ApplicationMap createMap(Range range, Range scanRange, List<List<SpanBo>> filterList) {
// Window의 설정은 따로 inject받던지 해야 될듯함.
// TODO inject TimeWindow from elsewhere
final TimeWindow window = new TimeWindow(range, TimeWindowDownSampler.SAMPLER);
@@ -233,7 +233,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
final DotExtractor dotExtractor = new DotExtractor(scanRange);
final ResponseHistogramBuilder mapHistogramSummary = new ResponseHistogramBuilder(range);
/**
* 통계정보로 변환한다.
* Convert to statistical data
*/
for (List<SpanBo> transaction : filterList) {
final Map<Long, SpanBo> transactionSpanMap = checkDuplicatedSpanId(transaction);
@@ -242,22 +242,22 @@ public class FilteredMapServiceImpl implements FilteredMapService {
final Application parentApplication = createParentApplication(span, transactionSpanMap);
final Application spanApplication = new Application(span.getApplicationId(), span.getServiceType());
// SPAN의 respoinseTime의 통계를 저장한다.
// records the Span's response time statistics
recordSpanResponseTime(spanApplication, span, mapHistogramSummary, span.getCollectorAcceptTime());
// 사실상 여기서 걸리는것은 span의 serviceType이 잘못되었다고 할수 있음.
if (!spanApplication.getServiceType().isRecordStatistics() || spanApplication.getServiceType().isRpcClient()) {
// span's serviceType is probably not set correctly
logger.warn("invalid span application:{}", spanApplication);
continue;
}
final short slotTime = getHistogramSlotTime(span, spanApplication.getServiceType());
// link의 통계값에 collector acceptor time을 넣는것이 맞는것인지는 다시 생각해볼 필요가 있음.
// 통계값의 window time으로 전환해야함. 안그러면 slot이 맞지 않아 oom이 발생할수 있음.
// might need to reconsider using collector's accept time for link statistics.
// we need to convert to time window's timestamp. If not, it may lead to OOM due to mismatch in timeslots.
long timestamp = window.refineTimestamp(span.getCollectorAcceptTime());
if (parentApplication.getServiceType() == ServiceType.USER) {
// 정방향 데이터
// Outbound data
if (logger.isTraceEnabled()) {
logger.trace("span user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId());
}
@@ -267,11 +267,11 @@ public class FilteredMapServiceImpl implements FilteredMapService {
if (logger.isTraceEnabled()) {
logger.trace("span target user:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId());
}
// 역관계 데이터
// Inbound data
final LinkDataMap targetLinkDataMap = linkDataDuplexMap.getTargetLinkDataMap();
targetLinkDataMap.addLinkData(parentApplication, span.getAgentId(), spanApplication, span.getAgentId(), timestamp, slotTime, 1);
} else {
// 역관계 데이터
// Inbound data
if (logger.isTraceEnabled()) {
logger.trace("span target parent:{} {} -> span:{} {}", parentApplication, span.getAgentId(), spanApplication, span.getAgentId());
}
@@ -313,7 +313,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
private void addNodeFromSpanEvent(SpanBo span, TimeWindow window, LinkDataDuplexMap linkDataDuplexMap, Map<Long, SpanBo> transactionSpanMap) {
/**
* span event statistics추가.
* add span event statistics
*/
final List<SpanEventBo> spanEventBoList = span.getSpanEventBoList();
if (CollectionUtils.isEmpty(spanEventBoList)) {
@@ -326,12 +326,12 @@ public class FilteredMapServiceImpl implements FilteredMapService {
ServiceType destServiceType = spanEvent.getServiceType();
if (!destServiceType.isRecordStatistics()) {
// internal 메소드
// internal method
continue;
}
// rpc client이면서 acceptor가 없으면 unknown으로 변환시킨다.
// 내가 아는 next spanid를 spanid로 가진 span이 있으면 acceptor가 존재하는 셈.
// acceptor check로직
// convert to Unknown if destServiceType is a rpc client and there is no acceptor.
// acceptor exists if there is a span with spanId identical to the current spanEvent's next spanId.
// logic for checking acceptor
if (destServiceType.isRpcClient()) {
if (!transactionSpanMap.containsKey(spanEvent.getNextSpanId())) {
destServiceType = ServiceType.UNKNOWN;
@@ -348,7 +348,7 @@ public class FilteredMapServiceImpl implements FilteredMapService {
if (logger.isTraceEnabled()) {
logger.trace("spanEvent src:{} {} -> dest:{} {}", srcApplication, span.getAgentId(), destApplication, spanEvent.getEndPoint());
}
// endPoint는 null이 될수 있음.
// endPoint may be null
final String destinationAgentId = StringUtils.defaultString(spanEvent.getEndPoint());
sourceLinkDataMap.addLinkData(srcApplication, span.getAgentId(), destApplication, destinationAgentId, spanEventTimeStamp, slotTime, 1);
}
@@ -75,14 +75,14 @@ public class LinkDataSelector {
}
/**
* callerApplicationName이 호출한 callee를 모두 조회
* Queries for all applications(callee) called by the callerApplication
*
* @param callerApplication
* @param range
* @return
*/
private LinkDataDuplexMap selectCaller(Application callerApplication, Range range) {
// 이미 조회된 구간이면 skip
// skip if the callerApplication has already been checked
if (linkVisitChecker.visitCaller(callerApplication)) {
return new LinkDataDuplexMap();
}
@@ -106,7 +106,7 @@ public class LinkDataSelector {
resultCaller.addSourceLinkData(link);
final Application toApplication = link.getToApplication();
// terminal, unknowncloud 인 경우에는 skip
// skip if toApplication is a terminal or an unknown cloud
if (toApplication.getServiceType().isTerminal() || toApplication.getServiceType().isUnknown()) {
continue;
}
@@ -117,7 +117,7 @@ public class LinkDataSelector {
resultCaller.addLinkDataDuplexMap(callerSub);
// 찾아진 녀석들에 대한 caller도 찾는다.
// find all callers of queried subCallers as well
for (LinkData eachCaller : callerSub.getSourceLinkDataList()) {
logger.debug(" Find callee of {}", eachCaller.getFromApplication());
LinkDataDuplexMap calleeSub = selectCallee(eachCaller.getFromApplication(), range);
@@ -129,14 +129,14 @@ public class LinkDataSelector {
}
/**
* callee applicationname을 호출한 caller 조회.
* Queries for all applications(caller) that called calleeApplication
*
* @param calleeApplication
* @param range
* @return
*/
private LinkDataDuplexMap selectCallee(Application calleeApplication, Range range) {
// 이미 조회된 구간이면 skip
// skip if the calleeApplication has already been checked
if (linkVisitChecker.visitCallee(calleeApplication)) {
return new LinkDataDuplexMap();
}
@@ -148,11 +148,11 @@ public class LinkDataSelector {
for (LinkData stat : callee.getLinkDataList()) {
calleeSet.addTargetLinkData(stat);
// 나를 부른 application을 찾아야 하기 떄문에 to를 입력.
// need to find the applications that called me
LinkDataDuplexMap calleeSub = selectCallee(stat.getFromApplication(), range);
calleeSet.addLinkDataDuplexMap(calleeSub);
// 찾아진 녀석들에 대한 callee도 찾는다.
// find all callees of queried subCallees as well
for (LinkData eachCallee : calleeSub.getTargetLinkDataList()) {
// terminal이면 skip
final Application eachCalleeToApplication = eachCallee.getToApplication();
@@ -169,7 +169,7 @@ public class LinkDataSelector {
private List<LinkData> checkRpcCallAccepted(LinkData linkData, Range range) {
// rpc client의 목적지가 agent가 설치되어 application name이 존재한다면 replace.
// replace if the rpc client's destination has an agent installed and thus has an application name
final Application toApplication = linkData.getToApplication();
if (!toApplication.getServiceType().isRpcClient()) {
return Arrays.asList(linkData);
@@ -187,7 +187,7 @@ public class LinkDataSelector {
final LinkData acceptedLinkData = new LinkData(linkData.getFromApplication(), first.getApplication(), linkData.getLinkCallDataMap());
return Arrays.asList(acceptedLinkData);
} else {
// specialcase 한개의 url에 2개의 노드가 묶여 있다.
// special case - there are more than 2 nodes grouped by a single url
return createVirtualLinkData(linkData, toApplication, acceptApplicationList);
}
} else {
@@ -203,8 +203,7 @@ public class LinkDataSelector {
List<LinkData> emulationLink = new ArrayList<LinkData>();
for (AcceptApplication acceptApplication : acceptApplicationList) {
// linkCallData를 바꿔야 한다.
// 일부러 callhistogram을 빼버린다.
// linkCallData needs to be modified - remove callHistogram on purpose
final LinkData acceptedLinkData = new LinkData(linkData.getFromApplication(), acceptApplication.getApplication(), linkData.getLinkCallDataMap());
emulationLink.add(acceptedLinkData);
traceEmulationLink(acceptedLinkData);
@@ -226,6 +225,8 @@ public class LinkDataSelector {
try {
// 호환성을 위해 일단 2번 뒤진다.
// 신데이터를 먼저 뒤지고 이후 구데이터를 뒤진다. 6개월 뒤에는 어차피 데이터가 없어지므로 호환성 코드를 지울것. 2014.07월 개발
// queries twice for backward compatibility - queries for the more recent version first
// FIXME Remove compatibility code after 6 monthes (from 2014.07)
acceptApplicationVer2 = findAcceptApplicationVer2(fromApplication, host, range);
logger.debug("findAcceptApplication2 {}->{} result:{}", fromApplication, host, acceptApplicationVer2);
} catch (HbaseSystemException ex) {
@@ -269,10 +270,8 @@ public class LinkDataSelector {
}
private void fillEmulationLink(LinkDataDuplexMap linkDataDuplexMap) {
// TODO 이쪽 부분은 추후에 ui가 들어오면 다시 구현이 필요하다.
// http://yobi.navercorp.com/Pinpoint/pinpoint-web/issue/193
// 현재는 역치환 관계 노드를 펼쳐만 놓았고, virtual node를 생성하여 rpc 데이터를 치환하는 로직은 넣지 못했음.
// virtual node 생성에 관련해서 추가적으로 많은 고민이 필요할듯하다.
// TODO need to be reimplemented - virtual node creation logic needs an overhaul.
// Currently, only the reversed relationship node is displayed. We need to create a virtual node and convert the rpc data appropriately.
logger.debug("this.emulationLinkMarker:{}", this.emulationLinkMarker);
List<LinkData> emulationLinkDataList = findEmulationLinkData(linkDataDuplexMap);
@@ -284,13 +283,13 @@ public class LinkDataSelector {
LinkKey findLinkKey = new LinkKey(emulationLinkData.getFromApplication(), emulationLinkData.getToApplication());
LinkData targetLinkData = linkDataDuplexMap.getTargetLinkData(findLinkKey);
if (targetLinkData == null) {
// 예외 케이스가 발생한적이 있는데. 정확한 이벤트를 캡쳐하지 못했음.
// 일단 error로 해둔후 문제 케이스를 추가로 잡아야 될듯함.
// There has been a case where targetLinkData was null, but exact event could not be captured for analysis.
// Logging the case for further analysis should it happen again in the future.
logger.error("targetLinkData not found findLinkKey:{}", findLinkKey);
continue;
}
// 역치환 데이터 생성. target이 accept한 데이터를 반대로 호출 데이터로 바꾼다.
// create reversed link data - convert data accepted by the target to target's call data
LinkCallDataMap targetList = targetLinkData.getLinkCallDataMap();
Collection<LinkCallData> beforeLinkDataList = beforeImage.getLinkDataList();
@@ -329,8 +328,8 @@ public class LinkDataSelector {
}
private List<LinkData> findEmulationLinkData(LinkDataDuplexMap linkDataDuplexMap) {
// emulationLinkMarker의 데이터를 직접 수정해도 LinkDataDuplexMap에서는 이미 데이터를 copy하여 사용하기 때문에 수정해도 효과가 없음.
// LinkDataDuplexMap에서 데이터를 다시 찾아야 한다.
// LinkDataDuplexMap already has a copy of the data - modifying emulationLinkMarker's data has no effect.
// We must get the data from LinkDataDuplexMap again.
List<LinkData> searchList = new ArrayList<LinkData>();
for (LinkData emulationLinkData : this.emulationLinkMarker) {
LinkKey search = getLinkKey(emulationLinkData);
@@ -26,7 +26,7 @@ import com.navercorp.pinpoint.web.vo.Range;
*/
public interface MapService {
/**
* 메인 화면의 서버 맵 조회.
* Queries for the Server Map
*
* @param sourceApplication
* @param range
@@ -64,7 +64,7 @@ public class MapServiceImpl implements MapService {
/**
* 메인화면에서 사용. 시간별로 TimeSlot을 조회하여 서버 맵을 그릴 때 사용한다.
* Used in the main UI - draws the server map by querying the timeslot by time.
*/
@Override
public ApplicationMap selectApplicationMap(Application sourceApplication, Range range) {
@@ -130,19 +130,18 @@ public class MapServiceImpl implements MapService {
private List<LinkDataMap> selectLink(Application sourceApplication, Application destinationApplication, Range range) {
if (sourceApplication.getServiceType().isUser()) {
logger.debug("Find 'client -> any' link statistics");
// client applicatinname + servicetype.client로 기록된다.
// 그래서 src, dest가 둘 다 dest로 같음.
// client is recorded as applicationName + serviceType.client
// Therefore, src and dest are both identical to dest
Application userApplication = new Application(destinationApplication.getName(), sourceApplication.getServiceTypeCode());
return mapStatisticsCallerDao.selectCallerStatistics(userApplication, destinationApplication, range);
} else if (destinationApplication.getServiceType().isWas()) {
logger.debug("Find 'any -> was' link statistics");
// destination이 was인 경우에는 중간에 client event가 끼어있기 때문에 callee에서
// caller
// 같은녀석을 찾아야 한다.
// for cases where the destination is a WAS, client events may be weaved in the middle.
// we therefore need to look through the list of callees with the same caller.
return mapStatisticsCalleeDao.selectCalleeStatistics(sourceApplication, destinationApplication, range);
} else {
logger.debug("Find 'was -> terminal' link statistics");
// 일반적으로 was -> terminal 간의 통계정보 조회.
// query for WAS -> Terminal statistics
return mapStatisticsCallerDao.selectCallerStatistics(sourceApplication, destinationApplication, range);
}
}
@@ -30,7 +30,7 @@ import java.util.List;
public interface ScatterChartService {
/**
* 필터를 사용한 검색.
* Queries for data using filter
*
* @param traceIds
* @param applicationName
@@ -40,7 +40,7 @@ public interface ScatterChartService {
List<Dot> selectScatterData(Collection<TransactionId> traceIds, String applicationName, Filter filter);
/**
* 전체 데이터 검색.
* Queries for data using time range.
*
* @param applicationName
* @param range
@@ -60,7 +60,7 @@ public interface ScatterChartService {
List<Dot> selectScatterData(String applicationName, SelectedScatterArea area, TransactionId offsetTransactionId, int offsetTransactionElapsed, int limit);
/**
* scatter dot limit 개수만큼 잘라서 조회하기 위해서 사용된다.
* Queries for scatter dots limited by the given limit.
*
* @param applicationName
* @param from
@@ -106,7 +106,7 @@ public class ScatterChartServiceImpl implements ScatterChartService {
}
/**
* scatter chart에서 선택한 점에 대한 정보를 조회 하는 메소드.
* Queries for details on dots selected from the scatter chart.
*/
@Override
public List<SpanBo> selectTransactionMetadata(final TransactionMetadataQuery query) {
@@ -121,14 +121,13 @@ public class ScatterChartServiceImpl implements ScatterChartService {
int index = 0;
for (List<SpanBo> spans : selectedSpans) {
if (spans.size() == 0) {
// 조회에 실패한 경우 span저장에 실패함.
// skip한다.
// span data does not exist in storage - skip
} else if (spans.size() == 1) {
// 1개 뿐이 없는 유일 케이스.
// case with a single unique span data
result.add(spans.get(0));
} else {
// 재귀일 경우 자신이 선택한 span이 어느 span인지를 선별해야 한다.
// 조회된 녀석들 중에서 transactionId, collectorAcceptor, responseTime이 같은것들만 선별.
// for recursive calls, we need to identify which of the spans was selected.
// pick only the spans with the same transactionId, collectorAcceptor, and responseTime
for (SpanBo span : spans) {
// 정확히 인덱스에 맞는 필터링 조건을 찾아야 함.
@@ -24,7 +24,7 @@ import com.navercorp.pinpoint.web.calltree.span.SpanAlign;
public class SpanDepth {
private final SpanAlign spanAlign;
private final int id;
// gap 을 구하기 위해 바로 전 lastExecuteTime을 구함
// needed for finding gap
private final long lastExecuteTime;
public SpanDepth(SpanAlign spanAlign, int id, long lastExecuteTime) {
@@ -79,7 +79,7 @@ public class SpanServiceImpl implements SpanService {
transitionSqlId(order);
transitionCachedString(order);
transitionException(order);
// TODO root span not found시 row data라도 보여줘야 됨.
// TODO need to at least show the row data when root span is not found.
return result;
}
@@ -117,7 +117,7 @@ public class SpanServiceImpl implements SpanService {
final AgentKey agentKey = getAgentKey(spanAlign);
// sqlId에 대한 annotation은 멀티 value가 날라옴.
// value of sqlId's annotation contains multiple values.
final IntStringStringValue sqlValue = (IntStringStringValue) sqlIdAnnotation.getValue();
final int hashCode = sqlValue.getIntValue();
final String sqlParam = sqlValue.getStringValue1();
@@ -138,7 +138,7 @@ public class SpanServiceImpl implements SpanService {
// AnnotationBo checkFail = checkIdentifier(spanAlign, sqlMetaDataBo);
// if (checkFail != null) {
// // 실패
// // fail
// annotationBoList.add(checkFail);
// return;
// }
@@ -168,13 +168,13 @@ public class SpanServiceImpl implements SpanService {
}
} else {
// TODO 보완해야됨.
// TODO need improvement
AnnotationBo api = new AnnotationBo();
api.setKey(AnnotationKey.SQL.getCode());
api.setValue(collisionSqlHashCodeMessage(hashCode, sqlMetaDataList));
annotationBoList.add(api);
}
// bindValue가 존재할 경우 따라 넣어준다.
// add if bindValue exists
final String bindValue = sqlValue.getStringValue2();
if (StringUtils.isNotEmpty(bindValue)) {
AnnotationBo bindValueAnnotation = new AnnotationBo();
@@ -198,7 +198,7 @@ public class SpanServiceImpl implements SpanService {
}
private String collisionSqlHashCodeMessage(int hashCode, List<SqlMetaDataBo> sqlMetaDataList) {
// TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음.
// TODO need a separate test case to test for hashCode collision (probability way too low for easy replication)
StringBuilder sb = new StringBuilder(64);
sb.append("Collision Sql hashCode:");
sb.append(hashCode);
@@ -220,7 +220,7 @@ public class SpanServiceImpl implements SpanService {
public void replacement(SpanAlign spanAlign, List<AnnotationBo> annotationBoList) {
final AgentKey key = getAgentKey(spanAlign);
final int apiId = getApiId(spanAlign);
// agentIdentifer를 기준으로 좀더 정확한 데이터를 찾을수 있을 듯 하다.
// may be able to get a more accurate data using agentIdentifier.
List<ApiMetaDataBo> apiMetaDataList = apiMetaDataDao.getApiMetaData(key.getAgentId(), key.getAgentStartTime(), apiId);
int size = apiMetaDataList.size();
if (size == 0) {
@@ -270,12 +270,11 @@ public class SpanServiceImpl implements SpanService {
if (size == 0) {
logger.warn("StringMetaData not Found {}/{}/{}", key.getAgentId(), stringMetaDataId, key.getAgentStartTime());
AnnotationBo api = new AnnotationBo();
// API METADATA ERROR가 아님. 추후 수정.
api.setKey(AnnotationKey.ERROR_API_METADATA_NOT_FOUND.getCode());
api.setValue("CACHED-STRING-ID not found. stringId:" + cachedArgsKey);
annotationBoList.add(api);
} else if (size >= 1) {
// key 충돌 경우는 후추 처리한다. 실제 상황에서는 일부러 만들지 않는한 발생할수 없다.
// key collision shouldn't really happen (probability too low)
StringMetaDataBo stringMetaDataBo = stringMetaList.get(0);
AnnotationBo stringMetaData = new AnnotationBo();
@@ -334,7 +333,6 @@ public class SpanServiceImpl implements SpanService {
if (metaDataList.size() == 1) {
return metaDataList.get(0);
} else {
// 일단 로그 찍고 처리.
logger.warn("stringMetaData size not 1 :{}", metaDataList);
return metaDataList.get(0);
}
@@ -359,7 +357,7 @@ public class SpanServiceImpl implements SpanService {
}
private String collisionApiDidMessage(int apidId, List<ApiMetaDataBo> apiMetaDataList) {
// TODO 이거 체크하는 테스트를 따로 만들어야 될듯 하다. 왠간하면 확율상 hashCode 충돌 케이스를 쉽게 만들수 없음.
// TODO need a separate test case to test for hashCode collision (probability way too low for easy replication)
StringBuilder sb = new StringBuilder(64);
sb.append("Collision Api DynamicId:");
sb.append(apidId);
@@ -66,7 +66,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
throw new NullPointerException("filter must not be null");
}
if (range == null) {
// TODO 레인지를 사용하지 않네. 확인필요.
// TODO range is not used - check the logic again
throw new NullPointerException("range must not be null");
}
@@ -86,7 +86,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
}
for (SpanBo spanBo : trace) {
// 해당 application으로 인입된 요청만 보여준다.
// show application's incoming requests
if (applicationName.equals(spanBo.getApplicationId())) {
businessTransactions.add(spanBo);
}
@@ -104,12 +104,12 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
RecordSet recordSet = new RecordSet();
// focusTimeStamp 를 찾아서 마크한다.
// span이 2개 이상으로 구성되었을 경우, 내가 어떤 span을 기준으로 보는지 알려면 focus시점을 찾아야 한다.
// 오류로 인해 foucs를 못찾을수 도있으므로, 없을 경우 별도 mark가 추가적으로 있어야 함.
// TODO 잘못 될수 있는점 foucusTime은 실제로 2개 이상 나올수 잇음. 서버의 time을 사용하므로 오차로 인해 2개가 나올수도 있음.
// finds and marks the focusTimestamp.
// focusTimestamp is needed to determine which span to use as reference when there are more than 2 spans making up a transaction.
// for cases where focus cannot be found due to an error, a separate marker is needed.
// TODO potential error - because server time is used, there may be more than 2 focusTime due to differences in server times.
SpanBo focusTimeSpanBo = findFocusTimeSpanBo(spanAlignList, focusTimestamp);
// focusTimeSpanBO를 못찾을 경우에 대한 임시 패치를 하였으나 근본적으로 해결된게 아님.
// FIXME patched temporarily for cases where focusTimeSpanBo is not found. Need a more complete solution.
if (focusTimeSpanBo != null) {
recordSet.setAgentId(focusTimeSpanBo.getAgentId());
recordSet.setApplicationId(focusTimeSpanBo.getApplicationId());
@@ -119,11 +119,11 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
}
// 기준이 되는 시작시간을 찾는다.
// find the startTime to use as reference
long startTime = getStartTime(spanAlignList);
recordSet.setStartTime(startTime);
// 기준이 되는 종료 시간을 찾는다.
// find the endTime to use as reference
long endTime = getEndTime(spanAlignList);
recordSet.setEndTime(endTime);
@@ -132,7 +132,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
logger.debug("RecordList:{}", recordList);
if (focusTimeSpanBo != null) {
// focus 대상 record를 체크한다.
// mark the record to be used as focus
long beginTimeStamp = focusTimeSpanBo.getStartTime();
markFocusRecord(recordList, beginTimeStamp);
recordSet.setBeginTimestamp(beginTimeStamp);
@@ -196,7 +196,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
}
}
}
// foucus Span을 찾지 못할 경우 firstSpan을 리턴한다.
// return firstSpan when focus Span could not be found.
return firstSpan;
}
@@ -205,7 +205,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
private final ApiDescriptionParser apiDescriptionParser = new ApiDescriptionParser();
// id가 0일 경우 root로 취급하는 문제가 있어 1부터 시작하도록 함.
// spans with id = 0 are regarded as root - start at 1
private int idGen = 1;
private final Stack<SpanDepth> stack = new Stack<SpanDepth>();
@@ -219,14 +219,13 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
}
final List<Record> recordList = new ArrayList<Record>(spanAlignList.size() * 2);
// annotation id spanalign seq와 무관하게 순서대로 따도 됨. 겹치지만 않으면 됨.
// annotation id has nothing to do with spanAlign's seq and thus may be incremented as long as they don't overlap.
for (int i = 0; i < spanAlignList.size(); i++) {
final SpanAlign spanAlign = spanAlignList.get(i);
if (i == 0) {
if (!spanAlign.isSpan()) {
throw new IllegalArgumentException("root is not span");
}
// spanAlign의 startTime을 넣을 경우 동일 시간으로 빼면 0이 나오므로 동일 값을 넣는다..
final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), spanAlign.getSpanBo().getStartTime());
stack.push(spanDepth);
} else {
@@ -236,15 +235,15 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
logger.debug("parentDepth:{} currentDepth:{} sequence:{}", parentDepth, currentDepth, lastSpanDepth.getId());
if (parentDepth < spanAlign.getDepth()) {
// 부모의 깊이가 더 작을 경우 push해야 한다.
// push if parentDepth is smaller
final SpanDepth last = stack.getLast();
final long beforeStartTime = getStartTime(last.getSpanAlign());
final SpanDepth spanDepth = new SpanDepth(spanAlign, getNextId(), beforeStartTime);
stack.push(spanDepth);
} else {
if (parentDepth > currentDepth) {
// 부모의 깊이가 클 경우 pop해야 한다.
// 단 depth차가 1depth이상 날수 있기 때문에. depth를 확인하면서 pop을 해야 한다.
// pop if parentDepth is larger
// difference in depth may be greater than 1, so pop and check the depth repeatedly until appropriate
SpanDepth lastPopSpanDepth;
while (true) {
logger.trace("pop");
@@ -257,7 +256,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
final long beforeLastEndTime = getLastTime(lastPopSpanDepth.getSpanAlign());
stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime));
} else {
// 바로 앞 동일 depth object는 버려야 한다.
// throw away the object right infront if it has the same depth
final SpanDepth before = stack.pop();
final long beforeLastEndTime = getLastTime(before.getSpanAlign());
stack.push(new SpanDepth(spanAlign, getNextId(), beforeLastEndTime));
@@ -276,7 +275,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
int parentSequence;
final SpanDepth parent = stack.getParent();
if (parent == null) {
// 자기 자신이 root인 경우
// root span
parentSequence = 0;
} else {
parentSequence = parent.getId();
@@ -326,7 +325,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
record.setFullApiDescription("");
recordList.add(record);
}
// exception이 발생했을 경우 record추가.
// add exception record
final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoSequence);
if (exceptionRecord != null) {
recordList.add(exceptionRecord);
@@ -359,7 +358,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed();
long elapsed = spanEventBo.getEndElapsed();
// stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌.
// use spanBo's applicationId instead of spanEventBo's destinationId to display the name of the calling application on the call stack.
Record record = new Record(spanAlign.getDepth(),
spanBoEventSequence,
parentSequence,
@@ -387,7 +386,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
long begin = spanAlign.getSpanBo().getStartTime() + spanEventBo.getStartElapsed();
long elapsed = spanEventBo.getEndElapsed();
// stacktrace에 호출한 application name을 보여주기 위해서 eventbo.destinationid 대신에 spanbo.applicaitonid를 넣어줌.
// use spanBo's applicationId instead of spanEventBo's destinationId to display the name of the calling application on the call stack.
Record record = new Record(spanAlign.getDepth(),
spanBoEventSequence,
parentSequence,
@@ -409,7 +408,7 @@ public class TransactionInfoServiceImpl implements TransactionInfoService {
recordList.add(record);
}
// exception이 발생했을 경우 record추가.
// add exception record
final Record exceptionRecord = getExceptionRecord(spanAlign, spanBoEventSequence);
if (exceptionRecord != null) {
recordList.add(exceptionRecord);
@@ -49,16 +49,16 @@ public class AcceptApplicationLocalCache {
public void put(RpcApplication findKey, Set<AcceptApplication> acceptApplicationSet) {
if (CollectionUtils.isEmpty(acceptApplicationSet)) {
// 비어 있는 값에 대해서도 생성해야 함.
// initialize for empty value
this.acceptApplicationLocalCache.put(findKey, acceptApplicationSet);
return;
}
logger.debug("findAcceptApplication:{}", acceptApplicationSet);
// build cache
// url 별로 AcceptApplicationData를 모은다.
// set AcceptApplication for each url
for (AcceptApplication acceptApplication : acceptApplicationSet) {
// acceptApplicationSet 데이터는 받은 url과 accept node applicationName을 저장하고 있음.
// 호출 application과 url을 기준으로 조회 키를 다시 생성해야 한다.
// acceptApplicationSet data contains the url and the accept node's applicationName.
// we need to recreate the key set based on the url and the calling application.
RpcApplication newKey = new RpcApplication(acceptApplication.getHost(), findKey.getApplication());
Set<AcceptApplication> findSet = this.acceptApplicationLocalCache.get(newKey);
if (findSet == null) {
@@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory;
import java.util.*;
/**
* 나중에 삭제하면 됨.
* remove later
* @author emeroad
*/
@Deprecated
@@ -46,7 +46,7 @@ public class AcceptApplicationLocalCacheV1 {
public void put(String host, Set<AcceptApplication> acceptApplicationSet) {
if (CollectionUtils.isEmpty(acceptApplicationSet)) {
// 비어 있는 값에 대해서도 생성해야 함.
// initialize for empty value
Set<AcceptApplication> emptySet = Collections.emptySet();
acceptApplicationLocalCacheV1.put(host, emptySet);
return ;
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* modify renderMergedOutputModel만 수정함.
* only modifies renderMergedOutputModel
* @author emeroad
*/
public class MappingJackson2JsonpView extends MappingJackson2JsonView {
@@ -55,7 +55,7 @@ public class TimeWindow implements Iterable<Long> {
}
/**
* timestamp를 윈도우 사이즈에 맞는 timestamp로 변환.
* converts the timestamp to the matching window slot's reference timestamp
*
* @param timestamp
* @return
@@ -39,7 +39,6 @@ public class TimeWindowDownSampler implements TimeWindowSampler {
public long getWindowSize(Range range) {
final long diff = range.getRange();
long size;
// 구간 설정 부분은 제고의 여지가 있음.
if (diff <= ONE_HOUR) {
size = ONE_MINUTE;
} else if (diff <= SIX_HOURS) {
@@ -42,10 +42,10 @@ public class TimeWindowSlotCentricSampler implements TimeWindowSampler {
}
/**
* <p>This implementation returns the window size that generates a
* <tt>MINIMUM_TIMESLOT.
* Additionally, the window size is calculated in multiples of a
* <tt>IDEAL_NUM_TIMESLOTS</tt>.
* <p>This implementation returns the window size that would generate the number of timeslots closest to
* <tt>idealNumTimeslots</tt> for a given <tt>range</tt>.
* <p>Additionally, the window size is generated in multiples of
* <tt>minTimeslot</tt>.
*
* @param range range to calculate the time window over
* @return size of the ideal time window
@@ -63,7 +63,7 @@ public class LinkSerializer extends JsonSerializer<Link> {
jgen.writeObjectField("histogram", histogram);
// 링크별 각 agent가 어떻게 호출했는지 데이터
// data showing how agents call each of their respective links
writeAgentHistogram("sourceHistogram", link.getSourceList(), jgen);
writeAgentHistogram("targetHistogram", link.getTargetList(), jgen);
@@ -79,7 +79,7 @@ public class LinkSerializer extends JsonSerializer<Link> {
}
private void writeWasToWasTargetRpcList(Link link, JsonGenerator jgen) throws IOException {
// was -> was 연결일 경우 호출실패시의 이벤트를 filtering 하기 위한 추가적인 호출정보를 알려준다.
// write additional information to be used for filtering failed WAS -> WAS call events.
jgen.writeFieldName("filterTargetRpcList");
jgen.writeStartArray();
Collection<Application> sourceLinkTargetAgentList = link.getSourceLinkTargetAgentList();
@@ -27,7 +27,7 @@ import com.navercorp.pinpoint.common.ServiceType;
public final class Application {
private final String name;
private final ServiceType serviceType;
// undefine일 경우 추적이 쉽도록 별도 데이터를 보관한다.
// store separately to track undefined cases more easily
private final short code;
public Application(String name, ServiceType serviceType) {
@@ -70,7 +70,7 @@ public class LoadFactor {
}
/**
* timeseries 기본값 채운다. 빈 공간은 그냥 적당히 채워준다. 모두 채우면 느리니까..
* initialize timeseries with default value.
*
* @return
*/
@@ -83,8 +83,8 @@ public class LoadFactor {
}
/**
* histogram slot을 설정하면 view에서 값이 없는 slot의 값을 0으로 보여줄 수 있다. 설정되지 않으면 key를
* 몰라서 보여주지 못함. 입력된 값만 보이게 됨.
* Empty slots in the view is shown as 0 if the histogram slot is set.
* If not, value cannot be shown as the key is unknown.
*
* @param schema
*/
@@ -129,7 +129,6 @@ public class LoadFactor {
successCount += callCount;
}
// TODO 이렇게 하는게 뭔가 좋지 않은것 같음.
if (responseTimeslot == -1) {
responseTimeslot = SLOT_ERROR;
} else if (responseTimeslot == 0) {
@@ -142,7 +141,7 @@ public class LoadFactor {
/**
* <pre>
* timeseriesValueList의 구조는..
* timeseriesValueList :
* list[respoinse_slot_no + 0] = value<timestamp, call count>
* list[respoinse_slot_no + 1] = value<timestamp, call count>
* list[respoinse_slot_no + N] = value<timestamp, call count>
@@ -151,8 +150,8 @@ public class LoadFactor {
for (int i = 0; i < timeseriesValueList.size(); i++) {
Map<Long, Long> map = timeseriesValueList.get(i);
// 다른 slot에도 같은 시간이 존재해야한다.
// FIXME responseTimeSlot의 자료형을 short으로 변경할 것.
// the same time should exist in different slots.
// FIXME change responseTimeSlot's data type to short
Integer slotNumber = timeseriesSlotIndex.get(responseTimeslot);
if (i == slotNumber) {
long v = map.containsKey(timestamp) ? map.get(timestamp) + callCount : callCount;
@@ -28,7 +28,8 @@ public class RangeFactory {
private TimeSlot timeSlot;
/**
* 역방향 분단위 통계 ragne 를 생성한다.
* Create minute-based reversed Range for statistics
*
* @param range
* @return
*/
@@ -36,8 +37,8 @@ public class RangeFactory {
if (range == null) {
throw new NullPointerException("range must not be null");
}
// hbase scanner를 사용하여 검색시 endTime은 검색 대상에 포함되지 않기 때문에, +1을 해줘야 된다.
// 단 key가 역으로 치환되어 있으므로 startTime에 -1을 해야함.
// HBase scanner does not include endTime when scanning, so 1 is usually added to the endTime.
// In this case, the Range is reversed, so we instead subtract 1 from the startTime.
final long startTime = timeSlot.getTimeSlot(range.getFrom()) - 1;
final long endTime = timeSlot.getTimeSlot(range.getTo());
return Range.createUncheckedRange(startTime, endTime);
@@ -31,7 +31,7 @@ public class ResponseTime {
private final ServiceType applicationServiceType;
private final long timeStamp;
// agentId key임.
// agentId is the key
private final Map<String, TimeHistogram> responseHistogramMap = new HashMap<String, TimeHistogram>();
@@ -17,7 +17,7 @@
package com.navercorp.pinpoint.web.vo;
/**
* FIXME 그냥 Range를 활용해도 될 듯..
* FIXME could just use Range..
*
* @author netspider
*
@@ -17,7 +17,7 @@
package com.navercorp.pinpoint.web.vo;
/**
* scatter chart에서 마우스로 드래그해서 선택한 영역의 정보
* Class representing the area selected in the scatter chart
*
* @author netspider
*
@@ -23,7 +23,7 @@ import com.navercorp.pinpoint.common.util.TransactionIdUtils;
/**
* @author emeroad
*/
// FIXME Comparable 인터페이스 제거.
// FIXME Remove Comparable interface
public class TransactionId implements Comparable<TransactionId> {
public static final int AGENT_NAME_MAX_LEN = PinpointConstants.AGENT_NAME_MAX_LEN;
public static final int DISTRIBUTE_HASH_SIZE = 1;
@@ -126,7 +126,7 @@ public class TransactionId implements Comparable<TransactionId> {
return TransactionIdUtils.formatString(agentId, agentStartTime, transactionSequence);
}
// FIXME 제거.
// FIXME remove
@Override
public int compareTo(TransactionId transactionId) {
int r1 = this.agentId.compareTo(transactionId.agentId);
@@ -26,7 +26,7 @@ import org.apache.commons.collections.CollectionUtils;
/**
* Time-series 처럼 연속된 데이터를 다운 샘플링한다.
* Down samples consecutive data points, such as a time-series dataset.
*
* @author harebox
* @author hyungil.jeong
@@ -38,7 +38,7 @@ public class Dot {
* @param transactionId
* @param acceptedTime
* @param elapsedTime
* @param exceptionCode 0 : 정상, 1 : error
* @param exceptionCode 0 : success, 1 : error
*/
public Dot(TransactionId transactionId, long acceptedTime, int elapsedTime, int exceptionCode, String agentId) {
if (transactionId == null) {
@@ -63,12 +63,13 @@ public class Dot {
}
/**
* ui에서 사용할 계층 화 되지 않은 단순 stateCode. 추후 계층화된 좀더 복잡한 코드 계층이 필요함.
* Simple stateCode used in the UI. May need to be fleshed out with state transitions in the future.
*
* @return
*/
public int getSimpleExceptionCode() {
if (getExceptionCode() == Dot.EXCEPTION_NONE) {
// 뭔가 fail이 1이상이어야 코드 추가가 되면서 정리가 될듯한데. 성공이 1이라 코드 정의가 애매함. 추후 수정이 필요함.
// feels like a failure should be a value greater 1
return Dot.SUCCESS_STATE;
} else {
return Dot.FAILED_STATE;
@@ -24,7 +24,8 @@ import java.util.Collections;
import java.util.List;
/**
* 나중에 @ResponseBody로 변경시 사용.
* To be used with @ResponseBody.
*
* @author emeroad
*/
public class ScatterScanResult {